Compare commits

..

983 Commits

Author SHA1 Message Date
Matthias Clasen
f425c3b7ab wayland: Rely on server key repeat info
Using gsettings for this information does not work
in sandboxed scenarios, where settings are per-app.
Since the Wayland protocol provides this information
nowadays, just drop the old code for reading
the gsettings.
2019-10-29 21:55:13 -04:00
Benjamin Otte
10911bfaf0 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.
2019-10-28 10:57:27 +01:00
Benjamin Otte
b36a58fa97 Add GtkColumnView skeleton
It's just a copy/paste of the listview code with all the internals
gutted. The code doesn't do anything.
2019-10-28 10:57:27 +01:00
Benjamin Otte
f978575e13 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.
2019-10-28 10:49:02 +01:00
Benjamin Otte
cabbe06c5b listbase: Take over anchor handling
With that, pretty much all code but allocating the widgets is gone from
the gridview and listview.
2019-10-28 10:49:02 +01:00
Benjamin Otte
f2044539ee 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.
2019-10-28 10:49:02 +01:00
Benjamin Otte
165d4e8307 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.
2019-10-28 10:49:02 +01:00
Benjamin Otte
2ba06352b1 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.
2019-10-28 10:49:02 +01:00
Benjamin Otte
f41f288fe7 listbase: Move orientable implementation here 2019-10-28 10:49:02 +01:00
Benjamin Otte
deb39d804d listbase: Move selection handling here 2019-10-28 10:49:02 +01:00
Benjamin Otte
f7f2d9ce98 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).
2019-10-28 10:49:01 +01:00
Benjamin Otte
010808794f listbase: Move GtkScrollable implementation
Shared code between GtkGridView and GtkListView.
2019-10-28 10:49:01 +01:00
Benjamin Otte
6ad943c400 Add GtkListBase
This is a base item for GTK's list widgets so they can share some (read:
hopefully a lot of) code.
2019-10-28 10:49:01 +01:00
Benjamin Otte
305d0aaae1 gridview: Simplify allocation code
It doesn't fix the bug I'm after, but it looks a lot better.
2019-10-28 10:49:01 +01:00
Benjamin Otte
e22f480af9 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.
2019-10-28 10:49:01 +01:00
Benjamin Otte
d479c4a6d4 demo: Add a file browser demo 2019-10-28 10:49:01 +01:00
Benjamin Otte
e7b523bc69 gridview: Add move keybindings 2019-10-28 10:49:01 +01:00
Benjamin Otte
367a711c9d 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.
2019-10-28 10:49:01 +01:00
Benjamin Otte
cc5808f99f gridview: Add a focus tracker
... and use that to properly update selections when moving around with
the arrow keys.
2019-10-28 10:49:01 +01:00
Benjamin Otte
408140bb09 gridview: Implement list.scroll-to action 2019-10-28 10:49:01 +01:00
Benjamin Otte
8b75d0c50a gridview: Add activation 2019-10-28 10:49:01 +01:00
Benjamin Otte
1a9b2d1110 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.
2019-10-28 10:49:01 +01:00
Benjamin Otte
c885a44d73 gridview: Implement the list.select-item action 2019-10-28 10:49:01 +01:00
Benjamin Otte
1499d1e68e 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.
2019-10-28 10:49:01 +01:00
Benjamin Otte
b2b001988f gridview: Implement anchors and scrolling 2019-10-28 10:49:01 +01:00
Benjamin Otte
bad5b5e8ed widget: Add gtk_widget_get_size()
A little bit of convenience.
2019-10-28 10:49:01 +01:00
Benjamin Otte
a9365373bb lul
https://i.imgur.com/iKX62LU.png
2019-10-28 10:49:01 +01:00
Benjamin Otte
51f9750339 listitemmanager: Handle NULL factory
Just don't call it and create empty listitems.
2019-10-28 10:49:01 +01:00
Timm Bäder
20efe0e501 demo: Use a listview as sidebar 2019-10-28 10:49:01 +01:00
Benjamin Otte
1dcf35c84d Add GtkExpression
This is the new replacement for bindings, though I'm not entirely sure
what I'm doing.
2019-10-28 10:49:01 +01:00
Benjamin Otte
4ea3d89ffe listitemfactory: Make the builder factory properly buildable
Turn the construct arguments into construct properties so that they can
be set from ui files.
2019-10-28 10:49:01 +01:00
Benjamin Otte
4d610f4b1f listview: Add move keybindings
My god, these are a lot.

And my god, these are complicated to get right.
2019-10-26 08:51:18 +02:00
Benjamin Otte
4fd5f96771 listview: Add gtk_list_view_get_position_at_y() 2019-10-26 08:51:18 +02:00
Benjamin Otte
7bddadf75f listitem: Add "listitem.select" action and keybindings for it
In fact, grab space with all modifiers to toggle selection of the
current item.
2019-10-26 08:51:18 +02:00
Benjamin Otte
cfde1598b5 listview: Add a focus tracker
This ensures that the row with the input focus always stays available,
even when scrolled out of view.
2019-10-26 08:51:18 +02:00
Benjamin Otte
c1d5d3036c 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.
2019-10-26 08:51:18 +02:00
Benjamin Otte
101095075c listview: Track focus movements and update selection
When focus moves via tab/arrow, we need to select the new item.
2019-10-26 08:51:18 +02:00
Benjamin Otte
16be945de2 listview: Implement activation
- a GtkListview::activate signal
- a GtkListItem::activatable property
- activate list items on double clicks and <Enter> presses
2019-10-26 08:51:18 +02:00
Benjamin Otte
3a27672f95 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.
2019-10-26 08:51:18 +02:00
Benjamin Otte
ed6aa467bc 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.
2019-10-26 08:51:17 +02:00
Benjamin Otte
ddd0218d97 popover: Remove unneeded vfunc
The vfunc is identical to the GtkWidget implementation it replaces. So
just keep using that one.
2019-10-26 08:51:17 +02:00
Benjamin Otte
538df82ea0 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.
2019-10-26 08:51:17 +02:00
Benjamin Otte
778a11748b inspector: Use a GtkTreeExpander in the object tree 2019-10-26 08:51:17 +02:00
Benjamin Otte
98941cd696 inspector: Use a treeexpander in the recorder 2019-10-26 08:51:17 +02:00
Benjamin Otte
9d33d8b92b 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.
2019-10-26 08:51:17 +02:00
Benjamin Otte
5b1b4290ca 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.
2019-10-26 08:51:17 +02:00
Benjamin Otte
baa564a3ba 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).
2019-10-26 08:51:17 +02:00
Benjamin Otte
3048d330b0 listview: Pass the CSS name of listitems to the manager
... instead of hardcoding "row".
2019-10-26 08:51:17 +02:00
Benjamin Otte
ef1eea6071 gridview: Implement GtkOrientable
Again, this is just the skeleton, because the Gridview does nothing yet.
2019-10-26 08:51:17 +02:00
Benjamin Otte
50f4ad6a38 gridview: Add factory handling
Just copy the listview APIs.

Code still doesn't do anything with it.
2019-10-26 08:51:17 +02:00
Benjamin Otte
399c275b1c 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.
2019-10-26 08:51:17 +02:00
Benjamin Otte
b7bdf99f54 textview: Make cursor work when blinking is disabled 2019-10-26 08:51:17 +02:00
Benjamin Otte
eae964a546 gtk-demo: Add a rough start at a Weather demo
This demos a horizontal listview.
2019-10-26 08:51:17 +02:00
Benjamin Otte
b326f8aed3 listview: Implement GtkOrientable 2019-10-26 08:51:17 +02:00
Benjamin Otte
aade4dd9bf tests: Add a rough form of multiselection
Just store a "filechooser::selected" attribute in the GFileInfo if
the file is meant to be selected.
2019-10-26 08:51:17 +02:00
Benjamin Otte
795f9f2cb5 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.
2019-10-26 08:51:17 +02:00
Benjamin Otte
7a864583cf listview: Add list.scroll_to_item action
The action scrolls the given item into view.

Listitems activate this action when they gain focus.
2019-10-26 08:51:17 +02:00
Benjamin Otte
523b600119 testlistview: Load icons async
Speeds up loading by 4x, because out of view icons aren't loaded
anymore.
2019-10-26 08:51:17 +02:00
Benjamin Otte
8d5cff3d91 directorylist: Add
Adds a new listmodel called GtkDirectoryList that lists the children of
a GFile as GFileInfos.

This is supposed to be used by the filechooser.
2019-10-26 08:51:17 +02:00
Benjamin Otte
795cb9e43b gtk-demo: Introduce awards
We need a way to get a useful listbox, so here we go!
2019-10-26 08:51:17 +02:00
Benjamin Otte
b9d639e34a 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.
2019-10-26 08:51:17 +02:00
Benjamin Otte
1d83e50f39 listitemfactory: Split implementation out
.. into gtkfunctionslistitemfactory.c

Now we can add a different implmenetation.
2019-10-26 08:51:17 +02:00
Benjamin Otte
8c960139dc listitemfactory: vfuncify
No functional changes other than a new indirection.
2019-10-26 08:51:17 +02:00
Benjamin Otte
c7092d07f4 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.
2019-10-26 08:51:17 +02:00
Benjamin Otte
5e273c957b listview: Add gtk_list_view_set_show_separators()
Do the same thing that GtkListBox does in commit
0249bd4f8a
2019-10-26 08:51:17 +02:00
Benjamin Otte
46feacf6b8 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.
2019-10-26 08:51:17 +02:00
Benjamin Otte
0353bb27d9 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.
2019-10-26 08:51:17 +02:00
Benjamin Otte
b5385dee22 gridview: Implement GtkScrollable
We can now scroll all the nothing we display.

We also clip it properly.
2019-10-26 08:51:17 +02:00
Benjamin Otte
bafa91580b listitemmanager: Move list of listitems here
All the listview infrastructure moved with it, so the next step is
moving that back...
2019-10-26 08:51:17 +02:00
Benjamin Otte
add133eb1d wayland: Remove function declaration for nonexisting function 2019-10-26 08:51:17 +02:00
Benjamin Otte
46e183f33d gridview: Add API for setting number of columns
The API isn't used yet.
2019-10-26 08:51:17 +02:00
Benjamin Otte
3c8323b11b gtk: Add a GtkGridView skeleton 2019-10-26 08:51:17 +02:00
Benjamin Otte
f350416c72 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.
2019-10-26 08:51:17 +02:00
Benjamin Otte
7a58bfd7ad listview: Add initial support for displaying selections 2019-10-26 08:51:17 +02:00
Benjamin Otte
ade9016987 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.
2019-10-26 08:51:17 +02:00
Benjamin Otte
b469c16c4e listview: Add selection properties to ListItem
This just brings the infrastructure into place, we're not using the
properties yet.
2019-10-26 08:51:17 +02:00
Benjamin Otte
febc5f2030 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.
2019-10-26 08:51:17 +02:00
Benjamin Otte
4530253974 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.
2019-10-26 08:51:17 +02:00
Benjamin Otte
2fd13bd601 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.
2019-10-26 08:51:17 +02:00
Benjamin Otte
89003822c3 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.
2019-10-26 08:51:17 +02:00
Benjamin Otte
0595e73a8b testlistview: Show the row number
Always show the current row. This is mostly useful for debugging, not
for beauty.
2019-10-26 08:51:17 +02:00
Benjamin Otte
154a9dfde6 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.
2019-10-26 08:51:17 +02:00
Benjamin Otte
8f34c13dfe 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.
2019-10-26 08:51:17 +02:00
Benjamin Otte
f9db1c38e7 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.
2019-10-26 08:51:17 +02:00
Benjamin Otte
0c1c0242ee 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.
2019-10-26 08:51:17 +02:00
Benjamin Otte
9afdd0ca3e tests: Make animating listview do random resorts 2019-10-26 08:51:17 +02:00
Benjamin Otte
79700acecb 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.
2019-10-26 08:51:17 +02:00
Benjamin Otte
849f67c198 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.
2019-10-26 08:51:17 +02:00
Benjamin Otte
6f57ced025 listview: Add GtkListItem
GtkListItem is a generic row widget that is supposed to replace
GtkListBoxRow and GtkFlowBoxChild.
2019-10-26 08:51:17 +02:00
Benjamin Otte
54b65ce465 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.
2019-10-26 08:51:17 +02:00
Benjamin Otte
47225f0ceb 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.
2019-10-26 08:51:16 +02:00
Benjamin Otte
90bb2c4133 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.
2019-10-26 08:51:16 +02:00
Benjamin Otte
d440dae1b7 listview: Implement GtkScrollable
Scrolling in a very basic form is also supported
2019-10-26 08:51:16 +02:00
Benjamin Otte
f0758a2af9 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.
2019-10-26 08:51:16 +02:00
Benjamin Otte
d11e075c2f 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.
2019-10-26 08:51:16 +02:00
Benjamin Otte
40ecd921b0 gtk: Add a GtkListView skeleton 2019-10-26 08:51:16 +02:00
Benjamin Otte
5aa45a2df9 builder: Allow parsing G_TYPE_BYTES from strings
Just create a bytes containing the literal string.
2019-10-26 08:51:16 +02:00
Benjamin Otte
801a3064bc togglebutton: Don't emit clicked during set_active()
set_active() is meant to set the state of the property, which happens
during setup.
The clicked signal is emitting events from user actions.

It is impossible to use Togglebuttons for MVC applications as long as it
does that.
2019-10-26 08:51:16 +02:00
Matthias Clasen
ba7649b388 inspector: Fix node recording
When attaching renderer-specific data, we need to
make sure that we key it off the renderer that is
in use, and cope with the absence of render data.

This fixes recording nodes in the inspector.
2019-10-18 09:33:45 -05:00
Piotr Drąg
239c178ef4 Update POTFILES.in 2019-10-17 20:11:58 +02:00
Matthias Clasen
fdbb925654 gl: Remove an unimplemented profiler counter 2019-10-17 07:59:34 -05:00
Matthias Clasen
aeabe3c40e gl: Add debug spew to texture atlas 2019-10-17 07:59:34 -05:00
Matthias Clasen
222b6c2b58 glyph cache: Go back to memcmp
Be careful to avoid padding data, and only
compare the relevant parts, leaving out the
hash key.
2019-10-17 07:59:34 -05:00
Matthias Clasen
5ab5ff7677 Cosmetics 2019-10-17 07:59:34 -05:00
Matthias Clasen
8a603ff5bd Revert "icon theme: Avoid a string copy"
This reverts commit 0895f0211e.

This negatively affected icons that are included as
resources, since peek_path returns NULL for them.
2019-10-17 07:16:30 -05:00
Goran Vidović
468295a9f7 Update Croatian translation 2019-10-17 12:03:32 +00:00
Matthias Clasen
6c92b824f3 Merge branch 'wip/chergert/opbuffer' into 'master'
Add OpBuffer helper for building op buffer

See merge request GNOME/gtk!1131
2019-10-17 11:37:07 +00:00
Goran Vidović
77e9788517 Update Croatian translation 2019-10-17 11:36:10 +00:00
Goran Vidović
0b1845b0cb Update Croatian translation 2019-10-17 11:23:00 +00:00
Benjamin Otte
342d88a1dc Merge branch 'otte/for-master' into 'master'
Otte/for master

See merge request GNOME/gtk!1136
2019-10-16 20:25:57 +00:00
Benjamin Otte
bab7f56f64 entry: Return boolean from gtk_entry_grab_focus_without_selecting()
This follows recent changes to gtk_widget_grab_focus().
2019-10-16 22:08:53 +02:00
Benjamin Otte
9b87cace47 render: Fix goto
if we have pushed a shadow, we better pop it again.

Broken since d1ea591f18
2019-10-16 21:45:33 +02:00
Benjamin Otte
c2a32afe97 Initialize cursor alpha to 1.0
That way, non-animated cursors don't disappear.
2019-10-16 21:45:33 +02:00
Benjamin Otte
d0e14f79a6 bindings: Make gtk_bindings_add_callback() allow for variant args 2019-10-16 21:45:33 +02:00
Benjamin Otte
7f2ab0d576 bindings: Refactor
Refactor code so that each bindings type has its own struct instead of
sharing one big union.
2019-10-16 21:45:33 +02:00
Timm Bäder
d36d7d93e6 Merge branch 'fix-popover-styles' into 'master'
Fix popover styles (GTK 4)

Closes #2061

See merge request GNOME/gtk!1079
2019-10-16 07:42:45 +00:00
Matthias Clasen
d777300d4e Fix a crash with glyph caching
We need to treat atlas-less cached glyphs like
atlases, when it comes to invalidating text node
render data.
2019-10-15 22:52:28 -04:00
Matthias Clasen
173bb2e1e8 gsk: Fix uninitialized memory
This was causing crashes in some circumstances.
2019-10-15 20:54:24 -04:00
Matthias Clasen
0895f0211e icon theme: Avoid a string copy
GIO has gained a way to peek at a GFile
path; lets use that.
2019-10-15 19:44:26 -04:00
Matthias Clasen
be13a23722 icon theme: Avoid mime sniffing
Themed icons are always pngs or svgs.
Take advantage of that to avoid costly
mime sniffing.
2019-10-15 19:44:26 -04:00
Matthias Clasen
7197743938 pixbuf utils: Preserve format information
When we are loading themed icons, we know if
we deal with an svg or png file, so it is
entirely unnecessarily to have gdk-pixbuf
use g_content_type guess to rediscover that
information.

Change the pixbuf utils apis we have to allow
passing format information down to where we
can use it when creating the pixbuf loader.
2019-10-15 19:44:26 -04:00
Matthias Clasen
dd5ee87b5b gl: Speed up icon cache lookups
Use gdk_texture_set_render_data to avoid
hash table lookups when we can.
2019-10-15 19:44:26 -04:00
Matthias Clasen
e34d1b8a26 gl: Slightly rework the icon cache api
Return a pointer to the IconData struct. This is
closer to the glyph cache api, and will allow us
to add similar shortcuts. For now, just store
texture coords in the form we need, avoiding
converting them over and over.
2019-10-15 19:44:26 -04:00
Matthias Clasen
c5af463843 Cache glyph textures in render nodes
This is a quick implementation that avoids many
glyph cache lookups. We keep an array of direct
pointers in the text render node, and throw those
cached pointers away whenever any atlases have
been dropped (since that may invalidate the cached
glyphs).
2019-10-15 19:44:26 -04:00
Matthias Clasen
49748c9c23 Some more vertex data reshuffling
In some cases, the vertex data is just a trivial
modification of the default data, so do that instead
of recalculating it.
2019-10-15 19:44:26 -04:00
Matthias Clasen
b53fa48794 Fix load_vertex_data
There was a copy-paste error that set all
uv coordinates to 0,0.
2019-10-15 19:44:26 -04:00
Christian Hergert
97f3371709 gl: avoid calculating vertex_data until necessary
In many cases of the switch, we do not need the vertex data. This moves
the creation of the vertex_data array into a secondary function and only
calculates it the cases for which it is required.
2019-10-15 19:44:26 -04:00
Matthias Clasen
58d57e1087 gl: Drop buffer_size
No need to maintain buffer_size separately.
It is always vertices->len * sizeof (GskQuadVertex).
2019-10-15 19:44:26 -04:00
Matthias Clasen
571068af12 Drop OP_CHANGE_VAO
Instead, we accumulate vertices in a separate
array, which simplifies various things and lets
us avoid the extra copying step for the vao.
2019-10-15 19:44:26 -04:00
Christian Hergert
a00d12c62a prototype OpBuffer helper for building op buffer 2019-10-15 19:44:26 -04:00
Benjamin Otte
7fc74eaeae Merge branch 'otte/for-master' into 'master'
Otte/for master

See merge request GNOME/gtk!1133
2019-10-15 18:47:57 +00:00
Benjamin Otte
4eb077979f widget: Don't grab focus when can-focus == false
... inside the default vfunc.

Instead, walk the children until we find the first widget that can be
focused. If no child can be focused, return FALSE from grab_focus.
2019-10-15 16:33:05 +02:00
Benjamin Otte
9c1b1eb894 widget: Insist that widgets are rooted to be focusable
This check was in the vfunc before, but it's a general rule, so apply it
before.
2019-10-15 16:33:05 +02:00
Benjamin Otte
14c34a7014 widget: Make grab_focus() fail on insensitive widgets
We can return FALSE early now instead of silently failing in
gtk_window_set_focus().
2019-10-15 16:33:05 +02:00
Benjamin Otte
427deb4f13 widget: Make gtk_widget_grab_focus() return a boolean
So now it can actually fail.

It doesn't yet though.
2019-10-15 16:33:05 +02:00
Benjamin Otte
a1a70a1130 bindings: Add gtk_binding_entry_add_callback()
This allows bindings that have no public API.
2019-10-15 07:17:30 +02:00
Benjamin Otte
19304c1d2c bindings: Add gtk_binding_entry_add_action()
Allows registering bindings for activating widget actions, as an
alternative to signal emissions.
2019-10-15 07:17:30 +02:00
Benjamin Otte
01be7f0666 widget: Make gtk_widget_activate_action() return TRUE/FALSE
TRUE if an action was successfully activated, FALSE if it wasn't found.
2019-10-15 07:17:30 +02:00
Benjamin Otte
1b68e76852 gtk: Add GtkNoSelection
Allows not to have anything selected.
2019-10-15 07:17:07 +02:00
Benjamin Otte
9f5ee77a44 singleselection: Fix model property
1. Make the model property construct-only. Allowing to change the
   model has invalid side effects.

2. Add a getter for the model property.
2019-10-15 07:17:07 +02:00
Benjamin Otte
6d20fe0bf9 expander: Rename CSS nodes
The expander icon is renamed from "arrow" to "expander".
The expander widget itself is renamed from "expander" to
"expander-widget" (Better ideas welcome).

This makes it possible to have an "expander" icon in more places then
the GtkExpander widget (in particular in tree lists) and not
confuse it with arrows.
2019-10-15 07:17:07 +02:00
Timm Bäder
bb56b4ef5d cssimagebuiltin: Don't create cairo nodes for empty icons
GTK_CSS_IMAGE_BUILTIN_NONE is not going to draw anything of course, so
don't bother creating an empty cairo node for it.
2019-10-15 07:13:28 +02:00
Timm Bäder
5ea21f7910 gl renderer: Fix an out of bounds read
Fixes #2200
2019-10-15 07:13:14 +02:00
Matthias Clasen
acb7f437fa notebook: Avoid a crash
This is fallout from turning the menu into
a popover, causing it to be be a child.
2019-10-12 19:00:35 -04:00
Matthias Clasen
7bff3abe8e glyph cache: Fix handling of big glyphs
We were putting big glyphs in the cache, in their
own texture, but forgetting to mark the texture
as permanent, so it could be reused, leading to
occasional misrendering. Fix this by marking these
textures as permanent, and explicitly freeing them
when the cache entry gets old.
2019-10-12 18:53:22 -04:00
Matthias Clasen
e46a7ca706 shadow cache: Remove outdated comments
No comments are better than outdated comments.
2019-10-12 17:06:39 -04:00
Matthias Clasen
e9ba7eda47 gl: Increate the cache check frequency
Otherwise, we spread the cache over more atlases
than necessary, increasing the amount of texture
changes in each frame.
2019-10-12 12:37:11 -04:00
Matthias Clasen
88649b6aae gl: Interleave cache aging
Every few frames, we do extra work for the
cache aging. Arrange for the glyph and icon
caches to not cause extra work on the same
frame, to smooth things out.
2019-10-12 12:37:11 -04:00
Matthias Clasen
60d63bbada gl: Improve debug spew for caches
Dump similar information for both caches,
and correct the unused percentage for
the atlases.
2019-10-12 12:37:11 -04:00
Timm Bäder
b8f62d1e10 Update stackswitcher CSS
Add the spacing to circular stack switchers back.
2019-10-12 18:26:54 +02:00
Timm Bäder
989307e4c2 stackswitcher: Inherit from GtkWidget 2019-10-12 18:12:58 +02:00
Timm Bäder
7344723a95 colorscale: Remove some duplicated code 2019-10-12 17:59:23 +02:00
Timm Bäder
4c4bca0c39 menuitem: Remove unused members 2019-10-12 17:59:23 +02:00
Timm Bäder
d570121704 menu: Align function parameters 2019-10-12 17:59:23 +02:00
Timm Bäder
93122ac935 menu: Remove unused members 2019-10-12 17:59:23 +02:00
Timm Bäder
f9e100cb1e menu: Remove menu_queue_resize
The have_layout flag is unused, so this is equal to a normal
gtk_widget_queue_resize().
2019-10-12 17:59:23 +02:00
Matthias Clasen
d3ad178d95 Merge branch 'glyphcache-fiddling' into 'master'
Glyphcache fiddling

See merge request GNOME/gtk!1132
2019-10-12 15:56:08 +00:00
Matthias Clasen
123cbd42bb gl: Make icon cache work like glyph cache
Replace timestamp tracking with an accessed bit
here too, to keep the glyph and icon cache code
similar.
2019-10-12 11:46:10 -04:00
Matthias Clasen
977ac2b31f gl: Do less work on glyph caching
There is no need for us to be very precise about
aging the glyph entries. It is enough to check
occasionally and mark old entries. This reduces
the overhead of work we do every frame on the
caches, at the cost of letting glyphs linger
a bit longer in the cache.
2019-10-12 11:35:46 -04:00
Timm Bäder
bcdc3b706c iconcache: Fix icon padding 2019-10-12 09:17:24 +02:00
Matthias Clasen
61db797f29 gl: Simplify glyph cache lookup
Make this function more similar to the icon
cache equivalent, and simplify it a bit. We
don't use the boolean return, and we don't need
to look at the age of entry when marking it
used.
2019-10-12 01:35:13 -04:00
Matthias Clasen
0a876f11a0 gl: Don't use memcmp for comparing cache keys
Some innocent change made us use a stack-allocated
key, and things broke. Lets go back to comparing
cache keys field by field.
2019-10-12 01:00:08 -04:00
Matthias Clasen
019e3c02ed Make the scrolling demo more versatile
Allow to swap out the content, so we can compare
text and icon scrolling.
2019-10-11 22:04:30 -04:00
Matthias Clasen
1c17316f9c gl: Handle row stride for icon cache upload
Same as the previous commit: Downloading a texture
may in theory give us data with a stride, so handle
that.
2019-10-11 21:17:30 -04:00
Matthias Clasen
646c5f369f gl: Handle row stride for glyph cache upload
In theory, we can have data with a stride here,
so set the necessary parameters to tell GL about
it.
2019-10-11 21:16:40 -04:00
Matthias Clasen
8839e10d44 gl: Do less work to maintain caches
Remember which atlases were removed, and only
check those when looking for icons or glyphs
to remove. For most frames, we don't have to
check at all since no atlases were removed.
2019-10-11 20:42:24 -04:00
Matthias Clasen
9b61bfb3c8 gl: Speed up icon caching
Avoid expensive padding, and just upload the
image in several slices.
2019-10-11 19:36:26 -04:00
Matthias Clasen
60e2242256 Add an icon scrolling demo
This is good to exercise the GL renderer icon cache.
2019-10-11 17:36:38 -04:00
Timm Bäder
4f5a9be465 gl renderer: Get blur node child only once 2019-10-11 22:31:33 +02:00
Timm Bäder
6a4c778791 gl renderer: Shorten function 2019-10-11 22:31:33 +02:00
Timm Bäder
1caa95b814 gl renderer: Avoid copying a rect 2019-10-11 22:31:33 +02:00
Matthias Clasen
cf44ba7847 gl: Avoid stray use of doubles
Everything else in this code is floats,
so stick to that and avoid unnecessary
precision.
2019-10-11 16:16:09 -04:00
Matthias Clasen
30433d7659 Cosmetics 2019-10-11 16:16:09 -04:00
Matthias Clasen
849b950763 gl: glyph cache tweaks
Reduce the cost of lookups by storing
the hash value directly.
2019-10-11 16:15:15 -04:00
Matthias Clasen
8937cd992d gl: Shrink CachedGlyph structs slightly
Plug a hole in this struct.
2019-10-11 16:15:14 -04:00
Matthias Clasen
e296c6a356 gsk: Store color bit info in text nodes
Keep the 'has color glyphs' info in text nodes,
instead of determining it over and over in both
the vulkan and gl backends.
2019-10-11 16:15:14 -04:00
Timm Bäder
136400e8a2 gl renderer: Remove unused modelview matrix 2019-10-11 16:56:24 +02:00
Timm Bäder
90199534e0 gl renderer: Don't copy outset shadow node outline 2019-10-11 16:38:58 +02:00
Timm Bäder
f7c64b4ebb gl renderer: Don't copy colors into render ops 2019-10-11 15:06:51 +02:00
Timm Bäder
f4f060c843 snapshot: Don't move shadows too much
dx/dy are relative to the node bounds, which are already moved by x/y.
2019-10-11 13:47:40 +02:00
Timm Bäder
2977e91aed gl renderer: Grow unblurred outset shadow outline on the gpu 2019-10-11 10:16:39 +02:00
Timm Bäder
0b999c73d1 gl renderer: Fix glsl rounded rect shrinking
Previous code would add rounded corners to a rect with all 0 corners
when growing.
2019-10-11 10:15:58 +02:00
Timm Bäder
9b1e0dd4a3 gl renderer: Cosmetics 2019-10-11 09:32:24 +02:00
Timm Bäder
a29826bb71 gl renderer: Only add outset shadow center piece if dx/dy != 0 2019-10-11 08:46:33 +02:00
Daniel Mustieles
a181136646 Updated Spanish translation 2019-10-10 14:00:22 +02:00
Matthias Clasen
5b04201da8 Merge branch 'wip/chergert/avoid-renderop-copy' into 'master'
gl: avoid copying RenderOp

See merge request GNOME/gtk!1128
2019-10-09 22:49:36 +00:00
Christian Hergert
528297f5e5 gl: avoid copying RenderOp to GArray
Instead of copying the (rather large) RenderOp to the GArray, we can
simply set the fields directly in the allocated space for the struct.
In most cases, there wont be any allocations to make as the array size
is kept in tact across frame renderings.
2019-10-09 15:41:53 -07:00
Christian Hergert
b29feb193e gl: use memcmp to compare glyph cache keys
We can just use memcmp here because even in the use of lookup keys with
C99 initializers, we can rely on any space between fields added by the
compiler to be zeroed. So we might as well use wider memory cmopares.
2019-10-09 14:47:23 -07:00
Matthias Clasen
75b5c2a293 Merge branch 'wip/chergert/const-glyph-cache' into 'master'
gl: avoid copying GskGLCachedGlyph in lookup

See merge request GNOME/gtk!1127
2019-10-09 21:45:41 +00:00
Christian Hergert
e32c992886 gl: avoid copying GskGLCachedGlyph in lookup
This saves a minor amount of CPU time by avoiding the copy of structure
on each lookup (which is short-lived).
2019-10-09 14:37:08 -07:00
Christian Hergert
c7a5d99286 textview: use gtk_snapshot_new_with_parent()
As recommended by Timm Bäder at:

3b959456ac (note_621655)
2019-10-09 12:56:06 -07:00
Christian Hergert
c9ca60c201 gl: short-circuit on NULL program
The NULL check is a more inclusive check than each of the individual
op->op checks.
2019-10-09 11:51:32 -07:00
Matthias Clasen
d9f6f26cd8 Merge branch 'wip/chergert/textview-fix-selection' into 'master'
textview: fix off-by-one in y_range invalidation

See merge request GNOME/gtk!1126
2019-10-09 17:50:40 +00:00
Christian Hergert
e4a00f864d textview: fix off-by-one in y_range invalidation
Previously, with selection bounds, we could have a state where a line
display with selections set would eroniously stay in the cache. This
aggresively releases those at the boundary cases fixing deselection
drawing state.
2019-10-09 10:43:34 -07:00
Timm Bäder
329f7c1c40 gl renderer: Remove rounded rect intersection code
Caused correctness issues.

Fixes #1917
2019-10-09 16:57:22 +02:00
Timm Bäder
c23afb2c86 widget: Compare adjusted sizes in size_allocate 2019-10-09 16:57:22 +02:00
Timm Bäder
e838ea3bc8 gl renderer: Fix scaled fallback node drawing 2019-10-09 16:57:22 +02:00
Timm Bäder
e5de03144f inspector: Don't add padding to spinbuttons
That looks stupid.
2019-10-09 16:57:22 +02:00
Timm Bäder
e325f65c8a spinbutton: Fix adjustment value thinko
Using ints here is wrong as it makes it impossible to e.g. edit a double
in the [0; 1] range.
2019-10-09 16:57:22 +02:00
Timm Bäder
2a40ff1b47 Adwaita: add statusbar padding back
We removed the widget margins from the ui file over 2 years ago.
2019-10-09 16:57:22 +02:00
Timm Bäder
371c325ed1 statusbar: Use a bin layout 2019-10-09 16:57:22 +02:00
Timm Bäder
542b95e7e8 widget-factory: Remove double border around textview
Replace the scrolledwindow border with two separator on top/bottom.
2019-10-09 16:57:22 +02:00
Timm Bäder
3d3525a589 stacksidebar: Inherit from GtkWidget
The child widgets are completely managed by the stacksidebar itself, so
this has no business being a GtkBin.
2019-10-09 16:57:22 +02:00
Timm Bäder
553c458e5a Adwaita: Remove superfluous border from stacksidebar
We already get a border from .sidebar
2019-10-09 16:57:22 +02:00
Timm Bäder
7cdb8d8565 gtk-demo: Fix up sidebar demo style
Remove a superfluous separator and add the icon-dropshadow class to the
gtk logo
2019-10-09 16:57:22 +02:00
Timm Bäder
172f68e77d popovermenu: Switch to main submenu before mapping 2019-10-09 16:57:22 +02:00
Timm Bäder
fb1145d72d popovermenu: Only close if there's a new focus widget
Makes sense and otherwise we end up closing the popover for no reason
2019-10-09 16:57:22 +02:00
Timm Bäder
bd9687a4f2 popovermenu: Switch back to "main" AFTER unmapping
Otherwise we might set things to child visible etc. while being
unmapped, which is a violation of the widget invariants of these
properties.
2019-10-09 16:57:22 +02:00
Timm Bäder
8928323c6b popover2.ui: Stop trying to set GtkModelButton:label
The property is called "text"
2019-10-09 16:57:22 +02:00
Timm Bäder
c7203550a2 testmodelbutton: Remove toggles for removed properties 2019-10-09 16:57:22 +02:00
Timm Bäder
49887d4c81 filechooserbutton: Only destroy existing native dialogs 2019-10-09 16:57:22 +02:00
Timm Bäder
d8c940325c widget: Create finalize assertions in destroy() 2019-10-09 16:57:22 +02:00
Timm Bäder
3944d64d08 demo: Don't manually add labels to menubuttons 2019-10-09 16:57:22 +02:00
Timm Bäder
e20f547317 demo: Fix modelbutton demo 2019-10-09 16:57:22 +02:00
Timm Bäder
a3cef6c05e label: Use TRUE/FALSE instead of 1/0 2019-10-09 16:57:22 +02:00
Timm Bäder
11ee72fc7e dialog: Fix action button rearrangement
The gtk_widget_get_parent() check does not work anymore since the
headerbar adds the buttons to a child box.
2019-10-09 16:57:22 +02:00
Timm Bäder
bcd8941769 widget-factory: Skip xml files in background selection dialog
The default contains a xml file for an animated background, so don't try
loading it as a pixbuf.
2019-10-09 16:57:22 +02:00
Timm Bäder
355d3f070a widget: Plug layout manager leak 2019-10-09 16:57:22 +02:00
Timm Bäder
b5b81dea7f modelbutton: Rework
Create all the widgets on demand and use a box layout to arrange them
instead of manual size allocation.

Also don't inherit from GtkButton
2019-10-09 16:57:21 +02:00
Timm Bäder
5803366f7d button: Remove unused signal enum members 2019-10-09 16:57:21 +02:00
Timm Bäder
d3fc47e149 modelbutton: Use a box layout 2019-10-09 16:57:21 +02:00
Timm Bäder
b8f37da911 modelbutton: Replace map() with root() 2019-10-09 16:57:21 +02:00
Timm Bäder
722f8e825e modelbutton: Remove end_box
it's unused.
2019-10-09 16:57:21 +02:00
Timm Bäder
a743412c58 modelbutton: Create accel label on demand 2019-10-09 16:57:21 +02:00
Timm Bäder
a6f14555d1 Adwaita: Blue check/radiobuttons
Align with 3.24.
2019-10-09 16:57:21 +02:00
Feichtmeier
1c091a03f3 Tiny refactoring
- use checkradio_fg_color for check/radio in treeview, which points to fg_color, so no change of the hex color, thus no change to the parsed CSS
2019-10-09 16:57:21 +02:00
frederik.feichtmeier
2dfb8de0ec Adwaita: Add color defines from 3.24 2019-10-09 16:57:21 +02:00
Jakub Steiner
876e256f94 Adwaita: make links in infobars legible
- No longer tinted blue, make legible

Fixes https://gitlab.gnome.org/GNOME/gnome-software/issues/751
2019-10-09 16:57:21 +02:00
Timm Bäder
eb834b8370 adwaita: Use border-spacing to style checkbuttons 2019-10-09 16:57:21 +02:00
Timm Bäder
dbabdf8341 radiobutton: Fix a warning in a code sample 2019-10-09 16:57:21 +02:00
Timm Bäder
703fda3be8 label: Remove set_selectable_hint
It's just updating the cursor, so do it via update_cursor()
2019-10-09 16:57:21 +02:00
Timm Bäder
2f6d6f2473 label: Remove gtk_label_realize
We don't need this to update the cursor anymore.
2019-10-09 16:57:21 +02:00
Timm Bäder
3f3c8436c5 label: Don't update cursor after unsetting select_info
update_cursor() doesn't do anything in the priv->select_info == NULL
case.
2019-10-09 16:57:21 +02:00
Timm Bäder
d8b0a78c1e label: Change cursor even if unrealized
Cursor don't depend on that anymore.
2019-10-09 16:57:20 +02:00
Timm Bäder
013538daf9 placesviewrow: popup-menu returns a boolean 2019-10-09 16:57:20 +02:00
Matthias Clasen
919d823311 Merge branch 'wip/carlosg/tablet-invalid-reads-master' into 'master'
Fix invalid reads on tablet input (master)

Closes #2157

See merge request GNOME/gtk!1122
2019-10-09 12:18:26 +00:00
Carlos Garnacho
075c77325b gdk: Avoid poking possibly freed memory
The event may end up freed after delivery, ensure to keep a ref in order
to emit the matching emulated crossed event matching a proximity event.

Closes: https://gitlab.gnome.org/GNOME/gtk/issues/2157
2019-10-09 10:35:50 +02:00
Matthias Clasen
5f8dc5459e Merge branch 'wip/chergert/quick-fixes' into 'master'
renderer quick fixes

See merge request GNOME/gtk!1124
2019-10-08 19:43:14 +00:00
Benjamin Otte
adff8c2c60 Merge branch 'wip/chergert/cache-text-render-node' into 'master'
textview: cache paragraph render nodes

See merge request GNOME/gtk!1125
2019-10-08 19:21:57 +00:00
Christian Hergert
3b959456ac textview: cache paragraph render nodes
We can avoid recreating a number of text nodes from render_para() on
sub-sequent runs if we cache the rendernode instead of just the
PangoLayout.

When used with GtkSourceMap, this can yield a ~7 FPS improvement during
smooth scrolling at the cost of some more memory.
2019-10-08 11:44:27 -07:00
Christian Hergert
47ef5af778 gl: remove stray + 2019-10-08 10:58:29 -07:00
Christian Hergert
76ea157f17 rendernode: remove unused macros 2019-10-08 10:57:45 -07:00
Carlos Garnacho
f354a7787a gdk: Fix wl_output accounting on tablet devices
The code managing this accounting mixed seat and tablet output lists,
can't bode well. Fixes invalid reads on list elements, as there are
dangling pointers.

Closes: https://gitlab.gnome.org/GNOME/gtk/issues/2157
2019-10-08 17:59:57 +02:00
Sam Hewitt
83eeeb6a19 Adwaita: circular button fix
- remove old border drawing code that was breaking coloured buttons
 - fixes #2173
2019-10-07 16:50:34 -04:00
Sam Hewitt
6db181980a Adwaita: osd button fixes
- remove text/icon shadow from osd buttons
 - use :only-child to get circular standalone button
 - fixes #1696
2019-10-07 15:27:55 -04:00
Sam Hewitt
023bb2c984 Adwaita: use borders_color for separators
- fixes #2175
2019-10-07 13:05:12 -04:00
Benjamin Otte
a3cfb42888 eventcontrollerkey: Change behavior of contains-focus
contains-focus now returns TRUE when is-focus is TRUE instead of FALSE.

Fixes #2184
2019-10-07 04:49:50 +02:00
Benjamin Otte
578dc9e70b eventcontrollerkey: Add getters for the properties
...and use them.
2019-10-07 04:49:50 +02:00
Benjamin Otte
6769db160d icontheme: Don't try to scale pixbufs to 0px
Always insist on at least 1px, even if the thumbnail we're turning into
an icon was 256 * 3 and should be scaled to 32 * 3/8.
2019-10-07 04:49:50 +02:00
Benjamin Otte
56d16aae42 selectionmodel: Remove doubled semicolon 2019-10-07 04:49:50 +02:00
Alan Mortensen
d614f4c96d Updated Danish translation of gtk 2019-10-06 23:36:47 +02:00
Daniel Boles
98f0d85c4a Builder: Fix a couple of typos in documentation 2019-10-06 20:48:10 +01:00
Piotr Drąg
b3115454ce Update POTFILES.in 2019-10-06 15:13:31 +02:00
Benjamin Otte
cb3b6ff624 Merge branch 'gbsneto/vulkan-fixes' into 'master'
Implement VK_KHR_incremental_present

See merge request GNOME/gtk!1116
2019-10-05 15:19:04 +00:00
Georges Basile Stavracas Neto
a795d6635b vulkan/context: Implement VK_KHR_incremental_present
This is the Vulkan version of eglSwapBuffersWithDamage(), and
it's always a good idea to limit the number of pixels we're
pushing to the GPU and/or swapping into the display.
2019-10-05 12:13:22 -03:00
Georges Basile Stavracas Neto
a2b49322fb vulkan/renderpass: Use GENERAL for initial layout
UNDEFINED initial layouts may not preserve the contents
of the attachment after transitioning the layout. We want
them to be preserved because we do partial rendering.

Use GENERAL as the initial layout for render passes.
2019-10-05 12:13:22 -03:00
Georges Basile Stavracas Neto
0b2006b74f vulkan/image: Set HOST and TRANSFER bits for before barriers
Multiple images in the before barrier array are defined with
VK_ACCESS_TRANSFER_WRITE_BIT and VK_ACCESS_TRANSFER_READ_BIT,
which requires passing VK_PIPELINE_STAGE_TRANSFER_BIT and
VK_PIPELINE_STAGE_HOST_BIT to vkCmdPipelineBarrier().

Pass these flags correctly.
2019-10-05 12:13:22 -03:00
Georges Basile Stavracas Neto
a91d0ac156 wayland: Allow binding to wl_compositor v4
This is a requirement for using VK_KHR_incremental_present.
Vulkan Wayland drivers translate the VkPresentRegionsKHR to
wl_surface.damage_buffer(), which a v4-only request.
2019-10-05 12:13:22 -03:00
Christian Hergert
d71995ab5c Merge branch 'wip/chergert/textview-widgets' into 'master'
textview: use GtkWidget for borders and center_child

See merge request GNOME/gtk!1099
2019-10-04 23:30:04 +00:00
Christian Hergert
fea2a82ef6 textview: use GtkTextViewChild for border and overlay children
This creates a new GtkTextViewChild that can manage overlay children at
given x,y offsets in buffer coordinates. This simplifies GtkTextView by
extracting this from GtkTextWindow as well as providing a real widget for
the borders.

With this change, we also rename gtk_text_view_add_child_in_window() to
gtk_text_view_add_overlay(). For those that were using
GTK_TEXT_WINDOW_WIDGET, they can use a GtkOverlay. It does not appear
that anyone was using GTK_TEXT_WINDOW_(LEFT|RIGHT|TOP|BOTTOM) for widgets
in this fashion, but that can be done by setting a gutter widget with
gtk_text_view_set_gutter(). We can make GtkTextViewChild public if
necessary to simplify this should it become necessary.

GtkTextViewChild will setup a CSS node of either "text" or "border"
depending on the GtkTextWindowType.

The old GtkTextViewChild has been renamed to AnchoredChild as it is only
used for widgets with anchors in the GtkTextBuffer. This also removes the
use of allocated GSList and instead embeds a GQueue and GList to save a
few extraneous allocations.
2019-10-04 14:45:43 -07:00
Christian Hergert
8373cc6c47 textview: revert renaming of buffer_to_surface_coords()
The renaming of this function doesn't make much since because the window
is the GtkTextWindowType, not GdkWindow specifically. So we can keep the
old name which is closer to the proper meaning and less code for consumers
to change when porting to 4.x.
2019-10-04 13:22:49 -07:00
Matthias Clasen
872d2046fd Merge branch 'list-box-headers' into 'master'
Fix reuse of list box header widgets

See merge request GNOME/gtk!1114
2019-10-04 18:27:05 +00:00
Sam Hewitt
44ec142fa9 Adwaita: new levelbar style 2019-10-04 14:16:11 -04:00
Philip Withnall
b70f389b64 gtklistbox: Only unparent header rows if they haven’t been reused
It’s possible for code which uses a `GtkListBox` to reuse a single
header row, and move it around between rows. For example, this might
happen if the code has interactive widgets (like buttons) in the row,
and doesn’t want to continually recreate them and reattach signals to
them whenever the row headers change.

Unfortunately, this was broken, as the old header widget was
unconditionally unparented, even if it had just been set as the header
for a different row in the same `GtkListBox`. This left it assigned as
a child widget in the `GtkListBox` (so it was iterated over by
`forall`), but without its parent widget set.

Fix that by only unparenting the header if it hasn’t already been
assigned as the parent of a different row.

Signed-off-by: Philip Withnall <withnall@endlessm.com>
2019-10-04 18:48:53 +01:00
Philip Withnall
1c73edd9b0 gtklistbox: Factor the new header out into a separate variable
Makes the code a little clearer, but makes no functional changes.

Signed-off-by: Philip Withnall <withnall@endlessm.com>
2019-10-04 18:48:51 +01:00
Christoph Reiter
94d9088034 Print a warning if GTK_DEBUG is set but gtk isn't built with G_ENABLE_DEBUG
G_ENABLE_DEBUG is tied to the meson builttype property, so building with "plain"
results in G_ENABLE_DEBUG not being defined and the GTK_DEBUG env var just gets ignored
for that build.

Since it can be confusing that GTK_DEBUG has no effect print a warning message instead.

See #2020. This is a port of !1109 to master
2019-10-02 21:35:20 +02:00
Ask Hjorth Larsen
cbd9e560b0 Updated Danish translation of gtk-properties 2019-10-02 05:54:14 +02:00
Ask Hjorth Larsen
abc595b810 Updated Danish translation of gtk 2019-10-02 05:54:12 +02:00
Marek Černocký
7d26d3926c Updated Czech translation 2019-10-02 02:06:50 +02:00
Georges Basile Stavracas Neto
0e55f7a52f wayland/surface: Fix crash when unexporting
This is the exact same problem of 655c9dd526.
2019-10-01 16:13:43 -03:00
Marek Černocký
febe128e72 Updated Czech translation 2019-10-01 17:32:46 +02:00
Georges Basile Stavracas Neto
3afc7b0883 Merge branch 'gbsneto/fix-wayland-export-handle' into 'master'
wayland/surface: Only call destroy func when available

Closes #2179

See merge request GNOME/gtk!1112
2019-10-01 15:22:22 +00:00
Georges Basile Stavracas Neto
655c9dd526 wayland/surface: Only call destroy func when available
When calling gdk_wayland_surface_export_handle(), if we pass
some 'user_data' but no 'destroy_func', GTK4 crashes. That's
because in xdg_exported_handle() we are unconditionally calling
destroy_func -- even when it's NULL.

Fix that by checking if there's a destroy function before calling
it.

Fixes https://gitlab.gnome.org/GNOME/gtk/issues/2179
2019-10-01 11:54:28 -03:00
Matej Urbančič
bcea96528a Updated Slovenian translation 2019-09-28 21:14:54 +02:00
Piotr Drąg
7336e18410 Update Polish translation 2019-09-28 13:59:24 +02:00
Aurimas Černius
412af0269d Updated Lithuanian translation 2019-09-28 12:51:44 +03:00
Matthias Clasen
5e17afbc0a Merge branch 'printing-get-ppd-from-original-host-if-needed' into 'master'
Printing get ppd from original host if needed

See merge request GNOME/gtk!1100
2019-09-27 19:24:00 +00:00
Benjamin Otte
912236439c Merge branch 'wip/ricotz/mediafile' into 'master'
mediafile: Use correct return-type for factory methods

See merge request GNOME/gtk!1105
2019-09-26 10:44:30 +00:00
Rico Tzschichholz
0ad4166482 mediafile: Add g-i annotations for actual return-type of factory methods 2019-09-26 08:19:25 +02:00
Timm Bäder
7ce1055656 eventcontrollerscroll: Events are unhandled by default
While the ::scroll signal always returns whether it handled the event,
the others do not, for example ::decelerate.

Previously, this caused the event to stop at a scroll controller with
CAPTURE phase, never emitting the ::decelerate signal on later
controllers with BUBBLE phase.

Fixes #2151
2019-09-25 17:51:53 +02:00
Timm Bäder
78a376aa7f snapshot: Try to avoid some linear gradient nodes 2019-09-25 17:51:52 +02:00
Timm Bäder
43f2b47fc9 searchentry: Use a box layout 2019-09-25 17:51:52 +02:00
Timm Bäder
413cfed7d7 searchentry: Use edit-clear-all-symbolic as clear icon
Fixes #2109
2019-09-25 17:51:52 +02:00
Timm Bäder
e05b87c8d0 gl renderer: Fix rounded rect intersection 2019-09-25 17:51:52 +02:00
Timm Bäder
1b4bce4182 fontchooserwidget: Use a bin layout 2019-09-25 17:51:52 +02:00
Timm Bäder
387587dedb colorbutton: Use a bin layout 2019-09-25 17:51:52 +02:00
Timm Bäder
5d8c8f33c0 dialog: Remove useless gtk_widget_show() call 2019-09-25 17:51:52 +02:00
Timm Bäder
d032396031 filechooserbutton: Add icon to default (None) combo box item
See #2118
2019-09-25 17:51:52 +02:00
Timm Bäder
12438b30a0 filechooserbutton: Remove priv->child
We never use it except when updating the state flags, but we can as well
do that for both children.
2019-09-25 17:51:52 +02:00
Timm Bäder
ea1ff9c482 filechooserbutton: Remove an outdated comment
The path used is wrong but the string isn't used in the testsuite
anyway.
2019-09-25 17:51:52 +02:00
Timm Bäder
8122156e84 scrolledwindow: Remove set_placement_internal()
set_placement() does the exact same thing.
2019-09-25 17:51:52 +02:00
Timm Bäder
991f4ed993 menubar: Use a box layout 2019-09-25 17:51:51 +02:00
Timm Bäder
29244c5c40 video: Use a bin layout 2019-09-25 17:51:51 +02:00
Timm Bäder
ca3d855c44 levelbar: Use a bin layout 2019-09-25 17:51:51 +02:00
Matthias Clasen
3fcd39f659 docs: Add GtkNative to types
This is needed to make doc generation work
for GtkNative.
2019-09-24 11:38:35 -04:00
Danial Behzadi
c2b823f185 Update Persian translation 2019-09-22 11:36:55 +00:00
Timm Bäder
7de076481e headerbar: Fix end-packed child order
We pack from right to left there.
2019-09-21 09:41:53 +02:00
Marek Kasik
58cfa3fd49 printing: Get PPD from original host if needed
Try to get PPD from original host if there is no PPD for remote printer
on current CUPS server.
2019-09-19 18:35:23 +02:00
Matthias Clasen
87e7fa9917 Merge branch 'wip/kill-menu' into 'master'
Use menus less

See merge request GNOME/gtk!1098
2019-09-16 22:10:02 +00:00
Matthias Clasen
b14b0efefe toolbar: Use a popover for overflow
We are phasing out menus.

This is not quite complete, toolitems still
create menuitems, which we translate on the fly.
2019-09-16 17:30:47 -04:00
Matthias Clasen
1b271f3335 notebook: Use a popover for the tab menu
We are phasing out menus.
2019-09-16 17:30:47 -04:00
Matthias Clasen
03e30431a8 menutoolbutton: Add support for popovers
Just like the underlying menu button, support
popovers too.
2019-09-16 07:24:59 -04:00
Matthias Clasen
5a93449b89 window: Make fallback menu a popover
We want to phase out menus.
2019-09-16 07:23:17 -04:00
Matthias Clasen
222e05c2d2 Remove unused includes
Don't include gtkmenu.h in places where
it isn't used anymore.
2019-09-16 07:23:17 -04:00
Matthias Clasen
c0071a0676 text util: Remove an unused function
_gtk_text_util_append_special_char_menuitems was not used.
2019-09-15 15:01:45 -04:00
Rico Tzschichholz
97231ca231 gtk: Fix some g-i annotation warnings 2019-09-15 17:57:28 +02:00
Rico Tzschichholz
67bd28eaaf gtk: Fix parameter annotations for gtk_buildable_parse_context_get_position 2019-09-15 17:57:28 +02:00
Rico Tzschichholz
51b2fd1777 build: gtkbuilderparser.c contains g-i annotations for public API 2019-09-15 17:57:28 +02:00
Matthias Clasen
ff5eac6da5 Merge branch 'wip/rah/screensaver-active-fix' into 'master'
gtkapplication-dbus: Initialise screensaver-active property

See merge request GNOME/gtk!1091
2019-09-15 15:54:08 +00:00
Matthias Clasen
4987cb0407 Merge branch 'wip/chergert/fix-textview-clip' into 'master'
textview: clip to text window when drawing

See merge request GNOME/gtk!1095
2019-09-14 21:18:02 +00:00
Christian Hergert
7927f7a440 textview: clip to text window when drawing
When drawing the GtkTextView text, we need to clip to the visible area
so that we do not risk drawing under the border windows.
2019-09-13 16:44:04 -07:00
Christian Hergert
605284bc36 textview: fix textview drawing in presence of gutters
When drawing a left or top gutter, we need to adjust the origin of the
text snapshot or we risk the gutter drawing above the text.
2019-09-13 16:02:28 -07:00
Timm Bäder
54ed31ebaf notebook: Use a box layout
And incidentally make the CSS node docs correct again.
2019-09-13 19:21:04 +02:00
Timm Bäder
6320bd5849 fontbutton: Shorten clear_font_data a bit 2019-09-13 19:21:02 +02:00
Timm Bäder
86cc7f6925 fontbutton: Use a bin layout 2019-09-13 11:53:24 +02:00
Timm Bäder
adb77e1a92 appchooserdialog: Remove unnecessary gtk_widget_show() calls 2019-09-13 11:39:34 +02:00
Timm Bäder
097f3c9514 headerbar: Remove spacing property
Replace it with border-spacing in css
2019-09-13 11:07:56 +02:00
Timm Bäder
f0266cbef3 pixbuf: Add a missing return value transfer annotation
And add a (nullable)
2019-09-13 11:07:56 +02:00
Timm Bäder
519967cc69 headerbar: Use a center layout
Get rid of the custom title centering etc. and use a GtkCenterLayout.
Use a box on the start/end to manage the child widgets.
2019-09-13 11:07:56 +02:00
Timm Bäder
a7b9a33efc Add GtkCenterLayout
And use it in GtkCenterBox, different widgets following.
2019-09-13 11:07:54 +02:00
Timm Bäder
32b84b8ab6 native: Don't compare a pointer with 0
We have NULL for that.
2019-09-11 08:12:31 +02:00
Timm Bäder
8ec1c866e1 widget: Inline build_finalize_assertions into only caller 2019-09-11 08:12:31 +02:00
Timm Bäder
3a06394fde headerbar: Don't update window buttons when unrealized
It doesn't make much sense in that case and we will update them again
when realizing.
2019-09-11 08:12:31 +02:00
Timm Bäder
ce72154913 Rename gtkbookmarkmanager.h to gtkbookmarksmanagerprivate.h
It's a private type, so gets a private header file name.
2019-09-11 08:12:31 +02:00
Timm Bäder
ed11f2a9e4 bookmarksmanager: Stop exporting get_xdg_type 2019-09-11 08:12:31 +02:00
Timm Bäder
60f2e452a1 switch: Stop using a private struct
Private type, no private struct needed.
2019-09-11 08:12:31 +02:00
Alexander Larsson
76103ee286 GtkBuildable: Fix indentation 2019-09-10 12:08:20 -04:00
Alexander Larsson
73042bfc54 GtkWidget: Precompile template xml on class creation
Ideally we will precompile during build and store the result in the
resource, but if that doesn't happen at least we will only parse
the xml once.
2019-09-10 12:08:20 -04:00
Alexander Larsson
ff23397701 GtkBuilder: Add support for precompiling builder xml 2019-09-10 12:08:20 -04:00
Alexander Larsson
96b37f4eb8 Use the new GtkBuildableParser type in GtkBuildable interfaces 2019-09-10 12:08:20 -04:00
Alexander Larsson
135cea76fb GtkBuildableParser: Add a wrapper for GMarkupParser
This currenly just wraps GMarkupParser, but the plan is to expose this
instead of GMarkup in the GtkBuildable interfaces, allowing us to
replace the parser with something that handles pre-parsed input
instead.

Note that we duplicate some of the features of GMarkup to implement
the APIs rather then call down to GMarkup, as we need to support these
in the pre-parsed case anyway.
2019-09-10 12:07:15 -04:00
Matthias Clasen
ff087e126f Merge branch 'wip/chergert/tune-linedisplay-cache' into 'master'
textview: optimize linedisplay cache based on number of visible rows

See merge request GNOME/gtk!1090
2019-09-10 01:42:13 +00:00
Matthias Clasen
9501fc2c14 Merge branch 'nested-popover-menu' into 'master'
Nested popover menus

See merge request GNOME/gtk!1076
2019-09-10 01:09:31 +00:00
Piotr Drąg
7547291450 Update POTFILES.in 2019-09-09 19:13:53 +02:00
Timm Bäder
0603b4431a icontheme: Stop using a private struct
The GtkIconTheme/GtkIconInfo structs aren't public anymore, so use the
structs directly instead of a priv pointer.
2019-09-09 17:36:27 +02:00
Timm Bäder
5f48f60a93 Icontheme: Clean up gtk_icon_info_load_async 2019-09-09 17:36:27 +02:00
Timm Bäder
cc9faf3cfa scrolledwindow: Actually add controller to widget
Closes #2127
2019-09-09 17:36:27 +02:00
Timm Bäder
7d93e9963a testlist2: quit on window close 2019-09-09 17:36:27 +02:00
Timm Bäder
32cec6c1cb icontheme: Adapt a code sample to the GdkPaintable transition 2019-09-09 17:36:27 +02:00
Timm Bäder
c0827e2c54 pixbufutils: Escape file data only once 2019-09-09 17:36:27 +02:00
Timm Bäder
1a931da046 pixbufutils: Pass colors as string to load_symbolic_svg
We were converting the same colors over and over again to a string, just
to free them again at the end of the function. We know the colors at
compile time however, so don't convert them at all.
2019-09-09 17:36:27 +02:00
Timm Bäder
8eb62f138b pixbufutils: Only get icon size once
load_symbolic_svg was loading the pixbuf just to get its size via
gdk_pixbuf_get_{width,height}. However, this function is called in a
loop in gtk_make_symbolic_pixbuf_from_data.

So, do this only once and pass the icon size along to load_symbolic_svg.
2019-09-09 17:36:27 +02:00
Timm Bäder
6a8921ec6b icontheme: Remove symbolic pixbuf cache
We recolor icons on via color matrix nodes these days, so this cache is
basically unused.
2019-09-09 17:36:27 +02:00
Timm Bäder
53132d0235 icontheme: Add LRU cache back
Add a cache of icon infos that we keep around a little longer, to avoid
loading icons from disk that only exist for a short amount of time (e.g.
during one frame of a cell renderer snapshot).

We make sure recently used items are kept alive by just adding them to
the cache on lookup.
2019-09-09 17:36:27 +02:00
Timm Bäder
32bed34935 icontheme: Remove GtkIconInfo->pixbuf
Create textures as soon as possible.
2019-09-09 17:36:26 +02:00
Timm Bäder
1873b38a94 icontheme: Remove icon_info_load_pixbuf
What it does overlaps with the only caller a lot now.
2019-09-09 17:36:26 +02:00
Timm Bäder
38b4a2a8e2 icontheme: Optimize suffix_from_name
We call this function a lot, so avoid repeated strlen() calls on @name
and the different suffixes.
2019-09-09 17:36:26 +02:00
Timm Bäder
b65d9ca955 icontheme: Avoid creating useless IconThemeDirs
We were allocating IconThemeDir instances and then only later assign a
value to has_icons. In the !has_icons case, we were directly throwing
the IconThemeDir away again.

Delay allocating the IconThemeDirs until we know that it has icons.
This avoids allocating and then de-allocating around 1400 IconThemeDir
instances when opening the widget-factory.
2019-09-09 17:36:26 +02:00
Timm Bäder
0b472c23d7 icontheme: Inline scan_resources into only caller
The previous code was hiding the fact that the scan_resources function
almost always did nothing and just used g_resources_enumerate_children()
and then returned FALSE, leaving the caller with cleaning up the already
allocated IconThemeDir. By inlining this, we make sure that calling code
does not even need to allocate the IconThemeDir.
2019-09-09 17:36:26 +02:00
Timm Bäder
bb89ee184f icontheme: Remove proxy pixbufs
These were only used for the LRU cache.
2019-09-09 17:36:26 +02:00
Timm Bäder
eb087c9943 icontheme: Remove lru cache
We will replace it with something else later
2019-09-09 17:36:26 +02:00
Timm Bäder
eeec6f8fb9 icontheme: Annotate return value as nullable 2019-09-09 17:36:26 +02:00
Timm Bäder
71339225eb icontheme: Remove gtk_icon_info_load_texture
It's the same as load_icon now.
2019-09-09 17:36:26 +02:00
Timm Bäder
590e70d4d1 icontheme: Return a paintable from gtk_icon_info_load_icon 2019-09-09 17:36:26 +02:00
Timm Bäder
fd16ac4d5e icontheme: Return paintables from more API 2019-09-09 17:36:26 +02:00
Timm Bäder
f3099afcc5 icontheme: Return textures from load_icon{,_for_scale} 2019-09-09 17:36:26 +02:00
Timm Bäder
37f8e6aabd gdk: Add gtk_pixbuf_get_from_texture 2019-09-09 17:36:26 +02:00
Timm Bäder
e0fe2882ad icontheme: Don't try to scale pixbufs to same size 2019-09-09 17:36:26 +02:00
Timm Bäder
4413592a70 recentmanager: Stop using linked lists
It doesn't really make sense to save the applications and groups in
recent infos as linked lists. We get them from glib as arrays, so we can
as well just save them as such.
2019-09-09 17:36:26 +02:00
Timm Bäder
4c28ee80a6 filechooserwidget: Create recent manager when setting operation mode
Creating a recent manager can be fairly expensive and we won't use it if
the widget is not visible or the recent mode has not been entered. Code
other places can already handle a NULL recent manager, so just create it
when entering the recent mode. And shove 25ms of startup time off the
widget-factory this way.
2019-09-09 17:36:26 +02:00
Timm Bäder
f4c4fe860b filechooserwidget: Remove custom recent_info_has_application impl 2019-09-09 17:36:26 +02:00
Timm Bäder
4766b475d0 filechooserwidget: Inline come functions into only callers
Similar to the previous commit(s), make it clearer what this function
does.
2019-09-09 17:36:26 +02:00
Timm Bäder
ae75d4b565 filechooser: Move extract_recent_folders to filechooserwidget
It's not used anywhere else.
2019-09-09 17:36:26 +02:00
Timm Bäder
c102387916 filechooserwidget: Load recent files synchronously
Delaying this by one frame by putting it in an idle just makes the code
more complex for no gain. The actual slow part is reading the
recently-used.xbel, which happens when creating the recent manager.
2019-09-09 17:36:26 +02:00
Timm Bäder
86ad215deb recentmanager: Indentation 2019-09-09 17:36:26 +02:00
Timm Bäder
c3f82534bd widget-factory: Use proper setter to set has-arrow 2019-09-09 17:36:26 +02:00
Timm Bäder
2ffbb37783 icontheme: Annotate return value of load_icon as nullable
It returns NULL in the error case.
2019-09-09 17:36:26 +02:00
Timm Bäder
6821fe0c13 icontheme: Add error argument to _load_texture
Loading an icon might fail.
2019-09-09 17:36:26 +02:00
Timm Bäder
a0947232fa icontheme: optimize icon_uri_is_symbolic as well 2019-09-09 17:36:26 +02:00
Timm Bäder
e3f1a3d27c main: Check if any debug flags are set in gtk_get_debug_flags()
We end up checking the debug flags for the default display, but that's
unnecessary if we know that no display has any debug flags set anyway.
2019-09-09 17:36:26 +02:00
Timm Bäder
d98e05b91a icontheme: Save the min_suffix for the min_dir
We already have to compute that value in the loop before, so just save
it.
2019-09-09 17:36:26 +02:00
Timm Bäder
fa85f4fc2e icontheme: Remove use_builtin parameter from theme_lookup_icon
Unused.
2019-09-09 17:36:26 +02:00
Timm Bäder
44352b375e icontheme: Remove paramter from get_icon_suffix
Turns out nobody care about that one.
2019-09-09 17:36:26 +02:00
Timm Bäder
ebe88ea322 icontheme: Optimize icon_name_is_symbolic
We call this function *a lot* it's doing lots of unnecessary work inside
g_str_has_suffix. Get the icon name length only once instead and
open-code the suffix check.
2019-09-09 17:36:26 +02:00
Timm Bäder
6d77723fe0 gtkicontheme: Avoid a get_icon_flags call
We're only using the value of the first call at all if
symbolic_suffix & ICON_SUFFIX_PNG is FALSE.
2019-09-09 17:36:26 +02:00
Timm Bäder
c5ed51a188 icontheme: Remove outdated comment
It's not called css_fg anymore and it can't possibly be NULL since we
make sure before passing it here.
2019-09-09 17:36:25 +02:00
Timm Bäder
1339c425a8 widget: Queue an allocate on native widgets when changing opacity
This way the opacity change works on toplevel windows on wayland.
2019-09-09 17:36:25 +02:00
Timm Bäder
7c723dfc58 inspect-button: Inline deemphasize_window() into only caller 2019-09-09 17:36:25 +02:00
Timm Bäder
72814a8153 inspect-button: Inline some functions into only caller
Make them clearer for later commits.
2019-09-09 17:36:25 +02:00
Timm Bäder
9952f72680 filechooserwidget: Properly watch for different display
The value returned by gtk_widget_get_settings() depends on the widget's
display, so watch for notify::display instead of using (un)root for
this.

Fixes the warnings seen when show a file chooser from the inspector.
2019-09-09 17:36:25 +02:00
Timm Bäder
b9473bc99c glarea: Fix buffer initialization
This only worked when the vao id and the buffer id accidentally matched,
for example when running gtk4-demo with --run=glarea

Fixes #2042
2019-09-09 17:36:25 +02:00
Timm Bäder
cbc3ce5b03 box: Don't do casts before preconditions 2019-09-09 17:36:25 +02:00
Timm Bäder
d223752c55 infobar: Inherit from GtkContainer
infobars being a GtkBox doesn't make sense.
Also implement infobars without exposing internal children.

Closes #1957 because it adds the bottom border.
2019-09-09 17:36:25 +02:00
Timm Bäder
74208e9e0c text: Fix a crash when retrieving the selected text 2019-09-09 17:36:25 +02:00
Timm Bäder
14b7fa1dd6 textview: Remove useless warning
The output doesn't make sense anymore and it breaks cursor blinking when
moving the focus back into the textview.
2019-09-09 17:36:25 +02:00
Timm Bäder
4bfe8605cb layoutoverlay: Fix everything
This code is better because:

  1) The coordinates translations are actually correct and not sometimes
     wrong like before
  2) We clip widgets that have overflow set
  3) We honor the widget's transform
  4) It is less code
2019-09-09 17:36:25 +02:00
Timm Bäder
e86bf764a8 scale: Allocate value close to slider
The scale might be allocated at a height greater than requested, and in
that case y=0 is just too far away. Allocate the value directly next to
the slider instead.
2019-09-09 17:36:25 +02:00
Timm Bäder
80411fb905 scale: Use top/left/bottom/right style classes on value label
Just top/bottom is not enough anymore.

77769a52b3 broke e.g. horizontal scales
with the value on top/bottom, adding too much space.
2019-09-09 17:36:25 +02:00
Timm Bäder
c9241e83dd gl renderer: Remove unused matrix 2019-09-09 17:36:25 +02:00
Timm Bäder
9166b03c42 fixed: Documentation clarifications 2019-09-09 17:36:25 +02:00
Timm Bäder
31efc882db fixed: x/y passed to get_child_position are not optional 2019-09-09 17:36:25 +02:00
Timm Bäder
1db59d1c89 fixedlayout: Don't call the child transform position
It's a full transform and not just a translation these days.
2019-09-09 17:36:25 +02:00
Timm Bäder
afb3715700 linkbutton: Use widget API to set has-toolip
As God intended.
2019-09-09 17:36:24 +02:00
Timm Bäder
6be4279f39 linkbutton: Use proper action name for right-click menu 2019-09-09 17:36:24 +02:00
Timm Bäder
5782871f91 menubutton: Control sensitivity of child button
Instead of the menubutton itself.
2019-09-09 17:36:24 +02:00
Timm Bäder
0e9ac9e64b magnifier: Remove some unused members 2019-09-09 17:36:24 +02:00
Timm Bäder
13df99fd1e docs: Remove styles.txt
The information is all wrong and superseded by the css docs
2019-09-09 17:36:24 +02:00
Timm Bäder
9f62bd1da6 docs: Remove widget_system.txt
Almost all information in here is incorrect or outdated, most of it is
still from gtk2 and GtkObject days.
2019-09-09 17:36:24 +02:00
Timm Bäder
75c1562df0 docs: Remove widget_geometry.txt
The information in that file is all outdated.
2019-09-09 17:36:24 +02:00
Timm Bäder
0821d5b29d widget: Clear up gtk_widget_class_install_property_action docs 2019-09-09 17:36:24 +02:00
Timm Bäder
b3cffc0516 widget: Remove reference to non-existent function
gtk_widget_class_install_stateful_action() does not exist.
2019-09-09 17:36:24 +02:00
Timm Bäder
80a58672d1 widget: Add some missing annotations to gtk_widget_class_query_action 2019-09-09 17:36:24 +02:00
Timm Bäder
18714e25a8 window: Remove useless deprecation guards
gtk_window_present() is not deprecated.
2019-09-09 17:36:24 +02:00
Timm Bäder
b29c30c9d5 cssprovider: Remove unused member from GtkCssScanner 2019-09-09 17:36:24 +02:00
Timm Bäder
d8df197489 cssprovider: Don't lookup on empty css providers
This should not have a huge performance impact, but debugging is easier
if we don't lookup in empty css providers.
2019-09-09 17:36:24 +02:00
Timm Bäder
514e60c1bb cssnode: GtkCssAnimatedStyle->style is always a static style 2019-09-09 17:36:24 +02:00
Timm Bäder
32a256bd03 gtksettings: Remove unused functions & prototypes 2019-09-09 17:36:24 +02:00
Timm Bäder
b9316a404a cssnode: Remove unused struct 2019-09-09 17:36:24 +02:00
Timm Bäder
ea2a3f3e62 cssstyle: Remove unused _add_difference 2019-09-09 17:36:24 +02:00
Timm Bäder
5cd8009c53 stylecontext: Remove leftover function prototypes 2019-09-09 17:36:24 +02:00
Timm Bäder
26aa620efe stylecontext: Stop exporting _resolve_color
Only used in gtkstylecontext.c
2019-09-09 17:36:24 +02:00
Timm Bäder
e0cf6e4775 csscolorvalue: return the initial color value directly 2019-09-09 17:36:24 +02:00
Timm Bäder
df2d43c893 csscolorvalue: Remove unused new_from_rgba() 2019-09-09 17:36:24 +02:00
Timm Bäder
8d6c5ba90e cssstaticstyle: Compute initial/inherit values directly 2019-09-09 17:36:24 +02:00
Timm Bäder
629f528f6d cssinitialvalue: Make _compute public
So we can use it in cases where the class of css value is known to be an
initial one.
2019-09-09 17:36:24 +02:00
Timm Bäder
191e3bc7e1 csslookup: Remove 'relevant' parameter from _init
Unused.
2019-09-09 17:36:24 +02:00
Timm Bäder
ecad4743bd csslookup: Remove 'missing' bitmask
It's almost never useful to have a bitmask here, since it's only used
for the intersection case in gtk_css_style_provider_lookup. However,
even if that returns true, we still need to check every single style
property for being set again in the look afterwards.

Just remove the bitmask.
2019-09-09 17:36:24 +02:00
Timm Bäder
ceb8aedf97 cssanimatedstyle: Keep transition_info_add from recursing
The slowest part of that fuction is the type check for
GtkCssShorthandProperty. Subproperties of shorthand properties never
refer to more shorthand properties however, so we don't want to have the
type check for those.
2019-09-09 17:36:24 +02:00
Timm Bäder
0cf4eb379f csslookup: Remove tautological if expression
A value is always either set or missing.
This was changed in a1f7c459b7, which
removed the ability for partial style computation.
2019-09-09 17:36:24 +02:00
Timm Bäder
f3fdf58ff7 cssstaticstyle: Avoid ref'ing specified value in compute_value
There are alerady _get functions for GtkCssInheritValue and
GtkCssInitialValue, so use those. We can avoid a ref+unref pair this
way.
2019-09-09 17:36:24 +02:00
Timm Bäder
3073e65851 cssprovider: Fix compilation wth VERIFY_TREE set 2019-09-09 17:36:24 +02:00
Timm Bäder
a75529f3c0 cssmatcher: Inline node values into matcher
So we don't have to go through the matcher->node->decl every time
2019-09-09 17:36:24 +02:00
Timm Bäder
75a48aed0b cssanimatedstyle: Make set_animated_value transfer-full 2019-09-09 17:36:24 +02:00
Timm Bäder
a7f23ebe7d cssimage: Use gtk_internal_return_val_*
GtkCssImage is not public and being used in hot paths, e.g. CSS.
2019-09-09 17:36:23 +02:00
Timm Bäder
0f9a02e6f4 gtkprivate: Only define gtk_internal_return_if* for consistency checks
The wanted behavior here is that these are only defined if the buildtype
is debug, i.e. full debugging.
2019-09-09 17:36:23 +02:00
Timm Bäder
4b4b77ca04 cssanimatedstyle: Save animation in array 2019-09-09 17:36:23 +02:00
Timm Bäder
a231648607 cssanimatedstyle: Avoid type check in loop
We can just do the check once as source is not going to change within
the loop.
2019-09-09 17:36:23 +02:00
Timm Bäder
eeb5cd2321 cssanimatedstyle: Avoid unnecessary transition work
No need to do all the transition work if the transition duration will be
0 for all of them.
2019-09-09 17:36:23 +02:00
Timm Bäder
5c705ae9a5 cssrgbavalue: Add & use new_white() 2019-09-09 17:36:23 +02:00
Timm Bäder
19f69f6ac8 cssrgbavalue: Add an opaque white singleton
Used a few hundred times in the widget-factory.
2019-09-09 17:36:23 +02:00
Timm Bäder
ad1340cab4 cssrgbavalue: Add a singleton for transparent colors
The most common background color is no background color.
2019-09-09 17:36:23 +02:00
Timm Bäder
3a3a59c188 cssdimensionvalue: Create a few more common singletons 2019-09-09 17:36:23 +02:00
Timm Bäder
6ed6cc46de cssstaticstyle: Make set_value (transfer-full)
We only call this in one place and we can avoid a ref + unref pair this
way.
2019-09-09 17:36:23 +02:00
Timm Bäder
6837e80d14 css: Avoid more type checks in hot paths 2019-09-09 17:36:23 +02:00
Timm Bäder
4f3e65e745 csspalettevalue: Use simple arrays instead of a hashtable
Use two sorted name/value arrays to save the colors instead of a
hashtable. This makes palette values faster to compare etc.
2019-09-09 17:36:23 +02:00
Timm Bäder
36a1b69a19 cssanimatedstyle: Remove some casts in hot paths
gtk_css_animated_style_create_css_transitions down from 16% to 11%
when repeatedly clicking on a spinbutton button in the widget factory.
2019-09-09 17:36:23 +02:00
Timm Bäder
1f11892de4 bitmask: Add _gtk_allocated_bitmask_to_string 2019-09-09 17:36:23 +02:00
Timm Bäder
1bc8f3ac6e Adwaita: Hack around list button styling
Once again.
2019-09-09 17:36:23 +02:00
Timm Bäder
e62f10d5f0 widget-factory: Add a spinbutton in a list 2019-09-09 17:36:23 +02:00
Timm Bäder
822547dfef spinbutton: Use a box layout 2019-09-09 17:36:23 +02:00
Timm Bäder
c0214cfcc1 menubutton: Add a create_popup_func
Some use cases require a menu button to create the popup on demand.
2019-09-09 17:36:23 +02:00
Timm Bäder
cb6d96d65f menubutton: Remove unused member 2019-09-09 17:36:23 +02:00
Timm Bäder
4cc4868e93 label: Remove "line" from wrap properties
The property names are "wrap" and "wrap-mode", so it doesn't make sense
that the accessors refer to line_wrap and line_wrap_mode.
2019-09-09 17:36:23 +02:00
Timm Bäder
6c90d3a1b6 gsktransform: Fix documentation comment
There is no @m.
2019-09-09 17:36:23 +02:00
Timm Bäder
ffab342fc4 snapshot: Stop exporting _append_node_internal
Unused outside of gtksnapshot.c
2019-09-09 17:36:23 +02:00
Matthias Clasen
1203dc501c popover menubar: Use nested popover menus
Make the popover menubar use nested menus, to
better match the expected behavior of traditional
menus.
2019-09-08 19:02:06 -04:00
Matthias Clasen
3cbf1845a9 Add a timeout for open submenus
When a popover menu has an open submenu,
delay activating another item until after
the pointer is stationary for a little
while. This avoids the need for precise
horizontal motion when moving towards the
submenu.
2019-09-08 19:02:06 -04:00
Matthias Clasen
ea44eade21 Add nesting popover menus
Add a variant of popover menus that are nesting
like traditional menus. This is a better fit for
replacing traditional main menus.
2019-09-08 19:02:06 -04:00
Matthias Clasen
c75a368bab popover: Support vertical aligment
We already support horizontal alignment, and
we should do the same for vertical alignment.
2019-09-08 19:02:06 -04:00
Matthias Clasen
bc8d2add04 widget-factory: Add more submenus
Split the "Checks & Radios" submenu in the menubar
into two, so we can test opening multiple submenus.
2019-09-08 19:02:06 -04:00
Timm Bäder
c53f58e839 Merge branch 'wip/chergert/remove-emit-by-name' into 'master'
texttag: avoid use of g_signal_emit_by_name()

See merge request GNOME/gtk!1088
2019-09-08 07:40:55 +00:00
Piotr Drąg
50543a7948 Update POTFILES.skip 2019-09-07 13:29:47 +02:00
Marek Černocký
f7cd22d5ec Updated Czech translation 2019-09-07 12:10:12 +02:00
Emin Tufan Çetin
b136c77031 Update Turkish translation 2019-09-06 18:50:05 +00:00
Bob Ham
6bfe171058 gtkapplication-dbus: Initialise screensaver-active property
When GtkApplication starts listening to the screensaver's D-Bus
status, the screensaver-active property is not initialised and
applications making use of the property are out of sync until the
first state change.  Any application starting when the screensaver is
active will think it's inactive.

To fix this, we set the property when we first start monitoring the
screensaver.
2019-09-06 14:59:27 +01:00
Christian Hergert
5e49da1d73 textview: optimize linedisplay cache based on number of visible rows
This tries to estimate the number of visible rows in a textview based on
the default text size and then tunes the GtkTextLineDisplayCache to keep
3*n_rows entries in the cache.

This was found imperically to be near the right cache size. In most cases,
this is less than the number of items we cache now. However, in some cases,
such as the "overview map" from GtkSourceView, it allows us to reach a
higher value such as 1000+. This is needed to keep scrolling smooth on
the larger view sizes.

With this patch, a HiDPI system with a GtkSourceView and GtkSourceMap
from the GTK 4 port can perform smooth scrolling simultaneously.
2019-09-05 19:06:35 -07:00
Christian Hergert
cc7ae525ef texttag: avoid use of g_signal_emit_by_name()
This avoids looking up the signal by name and instead uses the saved
signal identifier from gtktexttagtable.c
2019-09-04 19:39:24 -07:00
Matthias Clasen
a29853f53b Merge branch 'wip/chergert/faster-comparison' into 'master'
textlayout: remove use of GtkTextIter in line comparison

See merge request GNOME/gtk!1087
2019-09-04 17:02:06 +00:00
Christian Hergert
7cea21043e textlayout: remove use of GtkTextIter in line comparison
We do not need to create a GtkTextIter to perform the comparison here as
that will require a number of validation steps that are extra work
compared to just discovering the GtkTextLine number directly.
2019-09-04 09:12:54 -07:00
Matthias Clasen
cbdea09c92 Merge branch 'gtk-4-issue2128' into 'master'
[gtk4] wayland: Fix xdg-output v3 support

See merge request GNOME/gtk!1082
2019-09-03 14:38:30 +00:00
Olivier Fourdan
31393704de wayland: Fix xdg-output v3 support
The xdg_output.done event is deprecated in xdg-output v3, so clients
need to rely on the wl_output.done event instead.

However, applying the changes on the fist wl_output.event when using
xdg-output v3 may lead to an incomplete change, as following xdg-output
updates may follow.

Make sure we apply xdg-output events on wl_output.done events with
xdg-output v3.

https://gitlab.gnome.org/GNOME/gtk/issues/2128
2019-09-03 16:13:24 +02:00
nana-4
3eec90cdc0 node editor: Avoid inheriting textview styles
...to its descendant selectors

Without ">", "text" style is propagated to entry in the emoji chooser.

https://gitlab.gnome.org/GNOME/gtk/issues/2061
2019-09-03 01:44:55 +09:00
nana-4
b9d8eb54b7 Adwaita: Don't inherit font style to popover
https://gitlab.gnome.org/GNOME/gtk/issues/2061
2019-09-03 01:43:41 +09:00
nana-4
a2fdb55384 Adwaita: Fix broken osd popover style
Apply %osd to child arrow and contents instead of parent popover.

https://gitlab.gnome.org/GNOME/gtk/issues/2061
2019-09-03 01:34:05 +09:00
Jordi Mas
848a19a013 Update Catalan translation 2019-09-01 08:28:18 +02:00
Ryuta Fujii
98bc89968a Update Japanese translation 2019-08-31 13:45:30 +00:00
Ryuta Fujii
9c0e9e462b Update Japanese translation 2019-08-31 12:31:35 +00:00
Ryuta Fujii
57d762d5ea Update Japanese translation 2019-08-31 12:27:01 +00:00
Changwoo Ryu
9018ce1125 Update Korean translation 2019-08-30 14:10:45 +00:00
Timm Bäder
1b32f5c28b Merge branch 'typo' into 'master'
popover: fix typo in schema string

See merge request GNOME/gtk!1071
2019-08-29 13:56:13 +00:00
Alexandre Franke
0e35e50f8f Update French translation 2019-08-29 12:53:34 +00:00
Alexandre Franke
88b617646a popover: fix typo in schema string 2019-08-29 14:50:20 +02:00
Ask Hjorth Larsen
27fa7eace1 Updated Danish translation of gtk-properties 2019-08-29 12:37:41 +02:00
Ask Hjorth Larsen
ca996e0e85 Updated Danish translation of gtk 2019-08-29 12:37:41 +02:00
Jordi Mas
df683205d9 Update Catalan translation 2019-08-28 19:37:59 +02:00
Benjamin Otte
6905935fd3 Merge branch 'wip/ricotz/issue2107' into 'master'
gsk: Add missing 'transfer full' annotations of instance parameters

Closes #2107

See merge request GNOME/gtk!1065
2019-08-26 17:00:34 +00:00
Rico Tzschichholz
5504c62af9 gsk: Add missing 'transfer full' annotations of instance parameters
Fixes https://gitlab.gnome.org/GNOME/gtk/issues/2107
2019-08-26 18:05:17 +02:00
Matthias Clasen
9bb58c3eca Merge branch 'office-runner-crash' into 'master'
Fix a crash in gtk-builder-tool

See merge request GNOME/gtk!1064
2019-08-26 13:50:43 +00:00
Matthias Clasen
c0b8eb30de Fix a crash in gtk-builder-tool
Crash pointed out by Bastien Nocera.

Testcase included.
2019-08-26 15:34:15 +02:00
Changwoo Ryu
8a734f947e Update Korean translation 2019-08-26 11:20:16 +00:00
Timm Bäder
e4904f6644 Merge branch 'doc-typos' into 'master'
Minor typos in the Documentation (a/an)

See merge request GNOME/gtk!1061
2019-08-26 09:18:47 +00:00
Дилян Палаузов
6ded38de2b Minor typos in the Documentation (a/an) 2019-08-25 12:52:46 +00:00
Matthias Clasen
4fa1f459dd Merge branch 'gdkmonitor-x11-manufacturer' into 'master'
gdk: x11: Fill GdkMonitor manufacturer with PNP id from EDID

Closes #1765

See merge request GNOME/gtk!859
2019-08-25 11:58:02 +00:00
Balázs Úr
25644aa6b1 Update Hungarian translation 2019-08-24 20:23:45 +00:00
Anders Jonsson
a3f13f9c58 Update Swedish translation 2019-08-22 09:45:38 +00:00
Emmanuele Bassi
d940d801a4 Merge branch 'build-remove-xiproto-xreply-check-gtk4' into 'master'
Remove NEED_XIPROTO_H_FOR_XREPLY check

See merge request GNOME/gtk!1059
2019-08-21 19:18:17 +00:00
Christoph Reiter
7b0af75a57 Remove NEED_XIPROTO_H_FOR_XREPLY check
It was only defined in the old autotools build to support a >20 year old x11,
https://bugzilla.gnome.org/show_bug.cgi?id=148032
2019-08-21 20:46:30 +02:00
Daniel Mustieles
5329ac6d4b Updated Spanish translation 2019-08-20 12:45:23 +02:00
Daniel Șerbănescu
2b123702cc Update Romanian translation 2019-08-19 11:50:59 +00:00
Daniel Șerbănescu
56c2431ed1 Update Romanian translation 2019-08-19 11:09:45 +00:00
Aurimas Černius
0ed5f939e9 Updated Lithuanian translation 2019-08-18 21:41:16 +03:00
Kukuh Syafaat
f3fa4fcb75 Update Indonesian translation 2019-08-16 09:16:05 +00:00
Asier Sarasua Garmendia
bd35ff61e3 Update Basque translation 2019-08-16 08:01:11 +00:00
Asier Sarasua Garmendia
aa6f3a627f Update Basque translation 2019-08-16 07:55:49 +00:00
Timm Bäder
ee27587428 scale: Add a destroy notify to set_format_value_func
Closes #2098
2019-08-15 17:21:47 +02:00
Timm Bäder
d2f76d689f scaler: Avoid some signal connections
We're mainly using this for icons that will never change contents or
size, and we're using a GtkScaler per such icon when on a hidpi setup,
so just avoid the two signal connections per icon.
2019-08-15 17:13:29 +02:00
Timm Bäder
20cd6cc155 spinbutton: Use gtk_button_new_from_icon_name 2019-08-15 16:23:01 +02:00
Timm Bäder
960e766206 widget: Don't duplicate events to translate coordinates 2019-08-15 16:23:01 +02:00
Timm Bäder
1c9fbe3773 widget: Remove captured event handler code 2019-08-15 16:23:01 +02:00
Timm Bäder
6669ddad09 scrolledwindow: Stop using _gtk_widget_set_captured_event_handler
We can use an event controller with phase = CAPTURE these days.
2019-08-15 16:23:01 +02:00
Daniel Șerbănescu
6e872715ef Update Romanian translation
(cherry picked from commit 1e8d46352e)
2019-08-14 09:07:44 +00:00
Daniel Șerbănescu
dc582b478f Update Romanian translation
(cherry picked from commit 10603f9598)
2019-08-14 06:30:36 +00:00
Matthias Clasen
55839dc508 Merge branch '948-patch-renaming-a-file-can-make-it-to-loose-selection_GTK4' into 'master'
filechooser: keep file selected after being renamed

Closes #948

See merge request GNOME/gtk!1053
2019-08-13 21:18:41 +00:00
Matthias Clasen
6dd23b2bf0 text view: Fix a typo
Pointed out in https://gitlab.gnome.org/GNOME/gtk/issues/2094
2019-08-13 15:16:03 -04:00
Jordi Mas
afd64f3740 Update Catalan translation 2019-08-13 08:40:18 +02:00
Daniel Șerbănescu
a7b6663b33 Update Romanian translation
(cherry picked from commit f9acfa1bd8)
2019-08-13 04:37:32 +00:00
Nelson Benítez León
487e095d24 filechooser: keep file selected after being renamed
Because otherwise when the file list is sorted "by name"
and the new name causes the file to be re-sorted to another
row, the selection stays in the old row which is now
occupied by a different file.

Fixed by keeping track of the renamed file and revealing
it in the "row-changed" signal handler, which gets emitted
after a file is renamed.

Fixes issue #948
2019-08-12 17:32:56 -04:00
Daniel Șerbănescu
b487e8f694 Update Romanian translation 2019-08-12 08:35:22 +00:00
Piotr Drąg
171e3454ad Update Polish translation 2019-08-11 14:37:14 +02:00
Timm Bäder
164ebee129 Adwaita: Style spinbutton up/down children explicitly
Once again to increase the specificty above that of the
"list row button.etc." selector. Makes hovering spinbutton buttons in
lists look normal again.
2019-08-11 10:41:58 +02:00
Timm Bäder
76f2c4f0aa Adwaita: Update .devel headerbar styling
Just pull in the changes from gtk-3-24
2019-08-11 10:30:01 +02:00
Timm Bäder
9999ac1255 range: Avoid a divison by 0
Based on a patch by Blake Latchford

Fixes #618
2019-08-11 10:06:52 +02:00
Daniel Boles
3242174f81 AccelLabel: Add get_accel_closure() accessor
Fixes #875
2019-08-11 09:55:43 +02:00
Timm Bäder
6f1cade817 color chooser: Port checkered pattern drawing from cairo 2019-08-11 09:34:50 +02:00
Timm Bäder
c6961f1b61 range: Use public delay-factory API 2019-08-11 09:34:50 +02:00
Timm Bäder
8c88453816 cellrenderer: Add accessors for {get,set}_is_expande{r,d} 2019-08-11 09:34:50 +02:00
Timm Bäder
0415574acf testsuite: Add another repeat node test case 2019-08-11 09:05:31 +02:00
Timm Bäder
c812e1dc94 Adwaita: Fix hovering modelbutton arrows
This CSS snippet was supposed to only recolor the popover arrow but
ended up also recoloring the > arrow on modelbuttons that show a
submenu. Make the selector more specific.
2019-08-11 09:05:31 +02:00
Timm Bäder
251bf45cf2 iconcache: ref textures
We can't just assume that the pointer we'se using as a cache key will
stay unique forever. The texture might be freed, and a later allocated
texture might have the same addres now, causing the cache to return
incorrect results.
2019-08-11 09:05:31 +02:00
Timm Bäder
13c0a9e27b iconcache: Replace broken debugging code 2019-08-11 09:05:31 +02:00
Timm Bäder
4c70bf6c9c testsuite: Add a repeat node test case 2019-08-11 09:05:31 +02:00
Timm Bäder
2914c360a9 gl renderer: Implement a subset of repeat nodes 2019-08-11 09:05:31 +02:00
Timm Bäder
8d1a2247e0 treeview: Redo tree line drawing using textures
Gets rid of the remaining cairo nodes used for line drawing.
2019-08-11 09:05:28 +02:00
Timm Bäder
4fba7f8c59 treeview: Redo grid line drawing using textures
The cairo pattern in use was simple enough, so just use a 2×1 or 1×2
texture to draw horizontal and vertical grid lines. This avoids a bunch
of cairo nodes (that can't be cached by the renderers).
2019-08-11 09:05:25 +02:00
Timm Bäder
a93745238f snapshot: Annotate child_bounds parameter of push_repeat as nullable 2019-08-10 19:51:45 +02:00
Timm Bäder
b812ff2597 treeview: Shorten destroy() implementation 2019-08-10 19:51:45 +02:00
Timm Bäder
8a51796150 treeview: Remove two _dashes members
Tree lines and grid lines always look the same these days.
2019-08-10 19:51:45 +02:00
Timm Bäder
dd7d171186 treeview: Remove GTK_TREE_VIEW_FOREGROUND_LINE 2019-08-10 19:51:45 +02:00
Timm Bäder
0ac20f978e spinbutton: Remove an unnecessary queue_draw() call 2019-08-10 19:51:45 +02:00
Timm Bäder
0a96c3f062 scale: Properly update when inverted
Just queue_resize()ing the range itself doesn't work as it will just
re-allocate all the child widgets (i.e. just the trough) to its old
position and size.
2019-08-10 19:51:45 +02:00
Timm Bäder
42e6630c3e scale: Make a function shorter 2019-08-10 19:51:45 +02:00
Timm Bäder
1125d08f0d range: Remove outdated comment 2019-08-10 19:51:45 +02:00
Timm Bäder
0544633755 Merge branch 'wip/sadiq/buildable-2080' into 'master'
builderparser: Allow bind-source without bind-property

Closes #2080

See merge request GNOME/gtk!1047
2019-08-10 13:39:47 +00:00
Mohammed Sadiq
a642883e33 Add builder tests for bind-source without bind-property
Fixes https://gitlab.gnome.org/GNOME/gtk/issues/2080
2019-08-10 19:03:37 +05:30
Mohammed Sadiq
c1bb699151 builderparser: Allow bind-source without bind-property
This allow users to bind same property of two objects with only
specifing “name” and “bind-source” in UI file.

Fixes https://gitlab.gnome.org/GNOME/gtk/issues/2080
2019-08-10 19:01:36 +05:30
Daniel Șerbănescu
120cfcc120 Update Romanian translation 2019-08-10 07:25:36 +00:00
Mohammed Sadiq
55af84d359 widget: Fix a typo in documentation 2019-08-10 12:11:13 +05:30
Christian Hergert
4ae362d138 textview: clear cached entries before releasing containers
We want to ensure all of the display cache entries are released in the
normal fashion before releasing the structures so that we can maintain
the invariant that cache_iter will always exist while in the cache.
2019-08-09 12:52:16 -07:00
Timm Bäder
fd201e4df7 treeviewcolumn: Remove cell_area parameter from _cell_get_size
Fixes #297
2019-08-09 17:04:58 +02:00
Timm Bäder
21123a1264 iconhelper: Don't snapshot 0 sized icons
This is happening for me when snapshotting small thumbnails in the file
chooser. The GtkScaler will scale the 1px height/width by 2, resulting
in nothing being drawn at all.
2019-08-09 15:55:38 +02:00
Timm Bäder
87aeec2b63 scale: Fix value widget measurement
Since we set the size request of the label, the later measure()
call would return at least the size we set, making the size only ever
grow.
2019-08-09 14:30:01 +02:00
Timm Bäder
ea5fc348fa scale: Replace format-value signal
There is no reason for this to be a signal, since multiple handlers
don't make sense anyway. It was also broken because the scale needs to
know when a signal handler is added so it can update the value
representation.

Replace the signal with a set_format_value_func function which allows us
to do that.

Fixes #113
2019-08-09 14:30:01 +02:00
Timm Bäder
ebc0d3760f range: remove range_size_request vfunc
It's unneeded in GtkScale and named after the gtk2 size_request function
2019-08-09 14:30:01 +02:00
Timm Bäder
b4a6d69f5d scale: Allocate left marks next to trough 2019-08-09 14:30:01 +02:00
Timm Bäder
1c8b746b42 testscale: Properly call gtk_main_quit 2019-08-09 14:30:01 +02:00
Timm Bäder
05cdce2e8d scale: Fix an uninitialized value 2019-08-09 14:30:01 +02:00
Timm Bäder
509b781079 widget: Avoid a few type checks 2019-08-09 14:30:01 +02:00
Aurimas Černius
c38deef753 Updated Lithuanian translation 2019-08-09 14:21:11 +03:00
Timm Bäder
4b7a6a885d Merge branch 'adwaita-scales-marks-fintune-fix-master' into 'master'
Adwaita: Fix fine-tune mode for scales with marks

Closes #1799

See merge request GNOME/gtk!696
2019-08-08 16:41:04 +00:00
Benjamin Otte
68869a0e0f Merge branch 'wip/gtk-icon-theme-no-svg-loader' into 'master'
gtk/icon-theme: Handle lack of SVG loader gracefully

Closes #2084

See merge request GNOME/gtk!1049
2019-08-08 07:27:10 +00:00
Jonas Ådahl
048957cd49 gtk/icon-theme: Handle lack of SVG loader gracefully
When loading a SVG icon from a gresource file only containing SVG icons,
but without having a SVG loader available in gdk-pixbuf, we would crash
when trying to eventually load the resource. Fix this by gracefully
handling this by simply failing to load the icon, while the first time
it happens, log a warning.

Fixes: https://gitlab.gnome.org/GNOME/gtk/issues/2084
2019-08-08 09:05:30 +02:00
Timm Bäder
434d32bf95 Adwaita: Fix round titlebar button outline radius
Fixes #2073
2019-08-07 18:49:50 +02:00
frederik.feichtmeier
1178a0011a Exclude appmenu titlebuttons 2019-08-07 18:46:50 +02:00
frederik.feichtmeier
0af2e65c80 Make titlebuttons round
- use even sides for the titlebuttons so the result is a circle and not an ellipse
- add maximum border radius
- set min width/height to 0
- adjust margin and padding to match the previous look
2019-08-07 18:46:47 +02:00
Timm Bäder
e8f3b47bf3 gesturelongpress: Add getter/setter for delay-factor 2019-08-07 14:11:00 +02:00
Timm Bäder
8b16e44d26 passwordentry: Fix a documentation comment parameter name 2019-08-07 13:12:57 +02:00
Timm Bäder
002abc6d48 placessidebar: Remove popover using gtk_widget_unparent()
the gtk_widget_destroy() does not work anymore.
2019-08-06 17:39:01 +02:00
Timm Bäder
aca31c3ab6 adwaita: Increase spinbutton button styling specificity
So it trumps the 'toned down' button styling.

Fixes #2012
2019-08-06 17:38:54 +02:00
Priit Laes
f43d344aa3 gdk: x11: Fill GdkMonitor manufacturer with PNP id from EDID
Previously, the manufacturer property of the GdkMonitor was NULL,
and having at least PNP id at GdkMonitor.manufacturer makes it
possible to distinguish between different monitors programmatically.
2019-08-06 09:16:01 +03:00
Matthias Clasen
a3609c3f6d Merge branch 'implement-choices-file-chooser-native-win32-for-gtk-4' into 'master'
Implement choices for GtkFileChooserNativeWin32 [Gtk4]

Closes #1982

See merge request GNOME/gtk!1043
2019-08-05 12:20:06 +00:00
Jordi Mas
ddc74a08be Update Catalan translation 2019-08-05 06:18:53 +02:00
Jor Teron
76614ea5f2 Add Karbi translation 2019-08-04 18:24:49 +00:00
Jor Teron
2eabe21aae Add Karbi translation 2019-08-04 18:22:12 +00:00
Christian Kirbach
72f574a9c0 Update German translation 2019-08-04 16:16:01 +00:00
Luca Bacci
02935afe94 GtkFileChooserNativeWin32: Uninitialize COM at end of thread
GtkFileChooserNativeWin32 is created and shown on a secondary thread.
This thread initializes COM support with CoInitializeEx but does not
finalize it, so we have a leak. Fix that by calling CoUninitialize()
before thread terminates.

See Merge Request !1043
2019-08-04 18:03:37 +02:00
Luca Bacci
234d0443b2 GtkFileChoooserNative: change prepend to append for insertions in choices list
Although slightly less efficient, keeping the order in the choices
list makes it easier for GtkFileChooserNative implementations to
add widgets in the order specified by the application.

See Merge Request !1043
2019-08-04 18:03:21 +02:00
Luca Bacci
822deabdfe Implement choices for GtkFileChooserNativeWin32
See Merge Request !1043
2019-08-04 18:03:05 +02:00
Timm Bäder
b2e94f81cf window: Remove some leftover event code 2019-08-03 14:44:25 +02:00
Timm Bäder
109df77d87 popover: Use GTK_POS_BOTTOM as default position
This has always made a lot more sense.
2019-08-03 14:44:25 +02:00
Timm Bäder
76e3284ca1 colorchooserwidget: Inherit from GtkWidget
No reason for this to be a GtkBox.
2019-08-03 14:44:24 +02:00
Timm Bäder
576504390d supp: Add some more exceptions 2019-08-03 14:44:24 +02:00
Matthias Clasen
660f46fcb1 Merge branch 'glsl-switch' into 'master'
glsl: don't use switch statements

See merge request GNOME/gtk!1036
2019-08-02 16:59:27 +00:00
Matthias Clasen
2bd93c1e9e Merge branch 'wip/sort-icons-by-size' into 'master'
window: sort icons before adding to _NET_WM_ICON

See merge request GNOME/gtk!1038
2019-08-01 23:31:44 +00:00
Ray Strode
1612e38cda window: sort icons before adding to _NET_WM_ICON
When processing the list of icons for a window to add them to
_NET_WM_ICON gdk_x11_surface_set_icon_list only adds as many
icon sizes as will fit within X protocol limits.

It achieves this by keeping a running total of the number of
bytes taken up by icons already processed and bails as soon
as it goes over the limit.

The problem is, one 512x512 icon is already over the limit,
and so no icons will get added at all if the first icon in
list is 512x512.

Indeed, the code seems to assume the list is sorted from smallest
icon to biggest icon.

This commit changes the caller to sort the list.
2019-08-01 16:48:58 -04:00
Jordi Mas
176ab784dc Update Catalan translation 2019-08-01 20:19:06 +02:00
Matthias Clasen
b576aef2b1 Revert "gl: Simplify glyph cache rendering"
This reverts commit 7a3eaad193.

The reason we want to keep using pango here
is that we get hex boxes and similar drawing
features that way.
2019-08-01 00:18:19 -04:00
Elias Aebi
a357995484 glsl: don't use switch statements 2019-07-31 18:48:54 +02:00
Matthias Clasen
5d10100fc0 Merge branch 'glyph-cache-fixes' into 'master'
gl: Glyph cache fixes

See merge request GNOME/gtk!1034
2019-07-31 12:26:16 +00:00
Matthias Clasen
6118dfba74 Add missing includes 2019-07-31 08:04:03 -04:00
Matthias Clasen
d276d2629a gl: Glyph cache fixes
Pass the full location to the glyph cache lookup,
and use the same rounding as cairo does. This makes
the output much closer to the cairo renderer.
2019-07-31 00:03:13 -04:00
Matthias Clasen
e3ee1df456 Add an image comparison utility
This comes in handy sometimes, and we
already have the image diff code.
2019-07-30 14:02:43 -04:00
Daniel Mustieles
2691e4e949 Updated Spanish translation 2019-07-30 09:39:55 +02:00
Timm Bäder
20d7b7f59b widget factory: add a tooltip to a button in a popover 2019-07-30 07:05:45 +02:00
Matthias Clasen
1fcd08d76a Merge branch 'issue2057' into 'master'
Bump wayland-protocols requirements

See merge request GNOME/gtk!1030
2019-07-29 12:17:52 +00:00
Olivier Fourdan
060a9f072c Bump wayland-protocols requirements
The `name` and `description` events were added to `xdg-output` protocol
in version 2 which is part of wayland-protocols 1.14.

In xdg-output-v1 version 3, the `xdg-output.done` event was deprecated
and the `xdg-output.description` event was made mutable, but that
doesn't change the actual events so we do not actually need to require
that version of xdg-output from wayland-protocols 1.18.

Update the wayland-protocols requirement to the bare minimum version,
which is 1.14.

https://gitlab.gnome.org/GNOME/gtk/issues/2057
2019-07-29 12:03:07 +02:00
Matthias Clasen
4a631787bd Merge branch 'subpixel-positioning' into 'master'
Subpixel positioning

See merge request GNOME/gtk!1024
2019-07-28 21:02:31 +00:00
Matthias Clasen
032473fef8 reftest: Exclude flaky tests
These depend on details of text rendering,
and started failing with newer pango.
2019-07-28 16:42:52 -04:00
Matthias Clasen
5dd8801ee5 gl: implement subpixel positioning
Pass the glyph position into the glyph caching functions,
not just the glyph index. This allows us to cache different
images for different subpixel positions.
2019-07-28 16:42:52 -04:00
Matthias Clasen
5c9643b6eb vulkan: implement subpixel positioning
Pass the glyph position into the glyph caching functions,
not just the glyph index. This allows us to cache different
images for different subpixel positions.
2019-07-28 16:42:52 -04:00
Matthias Clasen
4de670b0b4 Turn off metrics hinting
This will be necessary to see the effects of subpixel positioning.
2019-07-28 16:42:52 -04:00
Matthias Clasen
ade40a7a0c Merge branch 'wip/chergert/textview-caching' into 'master'
textlayout: introduce caching for GtkTextLineDisplay

See merge request GNOME/gtk!1025
2019-07-28 20:32:56 +00:00
Christian Hergert
9926e6ebde textlayout: introduce caching for GtkTextLineDisplay
This adds a GtkTextLineDisplayCache which can be used to cache a number
of GtkTextLineDisplay (and thus, PangoLayout) while displaying a view.

It uses a GSequence to track the position of the GtkTextLineDisplay
relative to each other, a MRU to cull the least recently used display,
and and a direct hashtable to lookup display by GtkTextLine.

We only cache lines that are to be displayed (!size_only). We may want to
either create a second collection of "size_only" lines to speed that up,
or determine that it is unnecessary (which is likely the case).
2019-07-28 10:34:15 -07:00
Christian Hergert
b930c5a8a2 textiter: add _gtk_text_iter_same_line()
This is a faster form to compare two text iter to see if they are on the
same line.
2019-07-28 10:34:15 -07:00
Matthias Clasen
7eb5dfd294 inspector: Show the pango backend 2019-07-28 11:39:16 -04:00
Matthias Clasen
8752564fea Remove new attributes from tests
Until we can depend on pango 1.44, these will
fail in ci. Partially reverts f1c7803f80
2019-07-28 11:00:29 -04:00
Matthias Clasen
988fac404a Add pango version checks
Seems the ci does not have pango 1.44 yet.
2019-07-28 10:50:14 -04:00
Matthias Clasen
7a3eaad193 gl: Simplify glyph cache rendering
We are currently using a weird mix of pango and cairo,
but there is no need for us to go through a pango
renderer here; we can just use cairo directly.
2019-07-28 09:54:17 -04:00
Matthias Clasen
3fccb16ca6 gsk: Move text-related test out of ci
These are too sensitive to rendering differences
between renderers to run reliably in ci, but we
still want to keep them around. In particular,
the big glyph tests are useful to exercise the
GL glyph cache.
2019-07-28 09:35:37 -04:00
Timm Bäder
2c38b71ca5 glyph cache: Upload large glyphs in lookup () directly
Instead of relying on a texture id of 0, which can happen for other
reasons, e.g. when the glyph is being scaled too small.

Fixes part of #2046
2019-07-28 12:00:15 +02:00
Timm Bäder
1c93bef0d5 glyph cache: check glyphs for scaled size
We can't rely on just the ink_rect, since that might be without the
scaled applied, which is what ends up on the texture.

Fixes #2046
2019-07-28 10:58:10 +02:00
Timm Bäder
eea76e8cce textview: Remove some unnecessary gtk_widget_show() calls
Widgets are visible by default.
2019-07-28 08:44:45 +02:00
Jordi Mas
3b604331ec Update Catalan translation 2019-07-28 01:05:25 +02:00
Matthias Clasen
92546cf9f7 Merge branch 'overview-recursive-dependancy' into 'master'
overview.xml: The GTK library does not depend on the GTK library

See merge request GNOME/gtk!1026
2019-07-27 21:46:52 +00:00
Piotr Drąg
3c9f9d598b Update Polish translation 2019-07-27 15:20:40 +02:00
Piotr Drąg
ed46053dc9 Update POTFILES.skip 2019-07-27 15:03:47 +02:00
Дилян Палаузов
a3db7437b3 overview.xml: The GTK library does not depend on the GTK library
The documentation stated:

GTK is a library.…  GTK depends on the following libraries:

GTK       The GTK library itself contains widgets, that is, GUI
          components such as GtkButton or GtkTextView.

There is no point in stating, that the GTK library
depends on the GTK library.
2019-07-27 11:59:45 +00:00
Timm Bäder
b2d639b6d9 window: Unroot with old display
Things might rely on the old display being set while unrooting.

Fixes #2052
2019-07-27 07:57:06 +02:00
Matthias Clasen
f1c7803f80 label: Parse new pango attributes
Support allow-breaks and show attributes.
These will be in pango 1.44
2019-07-27 00:02:08 -04:00
Matthias Clasen
c179fce6c7 Merge branch 'xdg-output-v3-gtk4' into 'master'
wayland: Add xdg-output v3 support

See merge request GNOME/gtk!1022
2019-07-26 17:13:39 +00:00
Olivier Fourdan
795899f9d5 wayland: Add xdg-output v3 support
xdg-output v3 marks xdg-output.done as deprecated and compositors are
not required to send that event anymore.

So if the xdg-output version is 3 or higher, simply set the initial
value `xdg_output_done` to TRUE so we don't wait/expect that event
from the compositor.

https://gitlab.gnome.org/GNOME/gtk/issues/2053
2019-07-26 17:32:17 +02:00
Matthias Clasen
88ab3a6942 Merge branch 'wip/no-move-surface' into 'master'
Remove surface moving APIs

See merge request GNOME/gtk!1016
2019-07-26 14:31:49 +00:00
Timm Bäder
58e8dd1c0d gl renderer: Fix dx/dy handling on hidpi
Fixes misplaced error squiggles in the node editor.
2019-07-26 16:27:39 +02:00
Timm Bäder
b8bbf7b63b gl renderer: Rework transform handling
Fix all the ref counting mishaps. Makes hidpi work again and without
memory leaks.
2019-07-26 15:35:06 +02:00
Kukuh Syafaat
05e28fb498 Update Indonesian translation 2019-07-26 11:31:46 +00:00
Kjartan Maraas
c6d9963d1a Update Norwegian Bokmål translation 2019-07-26 09:01:15 +00:00
Daniel Mustieles
2d3a902beb Updated Spanish translation 2019-07-26 09:18:25 +02:00
Matthias Clasen
8b1f3936b6 font rendering demo: Make boxes optional 2019-07-26 00:31:07 -04:00
Matthias Clasen
108ea50179 font rendering demo: Show unrounded extents
This makes more sense.
2019-07-25 23:35:09 -04:00
Matthias Clasen
df1892c052 font rendering: Show ink rect too 2019-07-25 22:06:34 -04:00
Matthias Clasen
0820a79bf5 Improve the font rendering demo
Show the pixel grid, extents, and baseline.
2019-07-25 19:07:12 -04:00
Matthias Clasen
4427bde8a7 Merge branch 'fontrendering-demo' into 'master'
Add a font rendering demo

See merge request GNOME/gtk!1019
2019-07-25 21:06:54 +00:00
Matthias Clasen
dec4db5943 Add a font rendering demo
This renders a magnified version of the text,
to make the effect of various font rendering options
more visible.

It also shows the phases of subpixel rendering,
if you have a recent pango and cairo.
2019-07-25 16:43:22 -04:00
Matthias Clasen
fd7f6ca7ad tests: improve error handling 2019-07-25 13:51:34 -04:00
Matthias Clasen
dea309144b gtk-demo: Fix a crash 2019-07-25 13:51:34 -04:00
Emmanuele Bassi
f1e4efebb7 Merge branch 'gtk-4-add-TCRYPT-options-to-ask-password-dialog' into 'master'
gtkmountoperation: Add TCRYPT options to the ask-password dialog

See merge request GNOME/gtk!263
2019-07-25 10:16:11 +00:00
Jonas Ådahl
0885eb0a7b gdk: Remove gdk_surface_move_resize() API
Windows/surface's aren't supposed to be explicitly moved by any external
part, so don't provide API for doing so. Usage throughout Gdk is
replaced by the corresponding backend variants.
2019-07-25 10:35:43 +02:00
Jonas Ådahl
fc68d1b1e6 gdk: Make backends implement move_to_rect()
The generic layer still does the heavy lifting, leaving the backends
more or less just act as thin wrappers, dealing a bit with global
coordinate transformations. The end goal is to remove explicit surface
moving from the generic gdk layer.
2019-07-25 10:24:50 +02:00
Jonas Ådahl
b329090e69 gdk: Remove gdk_surface_move()
Generic gdk code now uses the internal helper; backends use their own
private implementations when necessary.
2019-07-25 10:24:50 +02:00
Jonas Ådahl
6314ebd435 gdk/surface: Add toplevel_resize vfunc
To separate how toplevels and popups are configured, a first step is to
introduce a resize-only vfunc for backends to implement. It's meant to
only configure toplevel windows, i.e. popups. Currently it's used for
both types, but introducing the resize-only API is a first step.
2019-07-25 10:24:50 +02:00
Matthias Clasen
e89e182565 Merge branch 'avoid-redundant-attributes' into 'master'
text layout: Avoid redundant text attributes

See merge request GNOME/gtk!1015
2019-07-24 23:47:41 +00:00
Matthias Clasen
552fe0406c text layout: Avoid redundant text attributes
Don't insert text attributes if the font, or scale
or fallback did not actually change. This helps
Pango avoid excessive item breaks, which in turn
helps shaping to work across things like color
changes.

Related: https://gitlab.gnome.org/GNOME/pango/issues/28
2019-07-24 19:05:32 -04:00
Jonas Ådahl
b062dea1aa wayland: Cleanup surface configuration
Configuration should happen in response to the xdg_surface.configure
event, not in the events that preceeds it. Do this by making all
configured state pending until the committing "configure" event. Also
split up toplevel vs popup configuration in a more clear way.
2019-07-24 22:42:37 +02:00
Jonas Ådahl
9b561581d5 wayland: Rename gdk_wayland_surface_configure to *_resize
It only issues a resize; configuring should imply more state is
configured, e.g. maximized, etc.
2019-07-24 22:42:37 +02:00
Jonas Ådahl
7f6c31c041 tests: Remove obsolete props from popover2.ui 2019-07-24 22:42:37 +02:00
Matthias Clasen
717c55c9aa Merge branch 'gtkapp-opening-str' into 'master'
Use commas to differentiate between text and filename

See merge request GNOME/gtk!1013
2019-07-24 13:51:22 +00:00
Jordi Mas
7d1c6272be Use commas to differentiate between text and filename 2019-07-24 13:51:22 +00:00
Matthias Clasen
2f387c2a23 Merge branch 'missing-gobject-annotation' into 'master'
Add nullable annotation to combo_box_text_get_active_text

See merge request GNOME/gtk!1012
2019-07-24 13:50:04 +00:00
Timm Bäder
0d95c5dfe2 passwordentry: Normalize boolean value 2019-07-24 08:10:37 +02:00
Timm Bäder
f2a2908c59 passwordentry: Remove empty vfunc implementation 2019-07-24 08:10:26 +02:00
Timm Bäder
f4cb60dcca textlayout: Avoid querying CSS state if we don't have to
This is actually pretty slow, and we almost never render a selection.
2019-07-24 07:54:30 +02:00
Timm Bäder
b3d0629709 popover: Remove some unnecessary checks
gtk_popover_move_resize() already checks whether the popover has a
surface.
2019-07-24 07:54:30 +02:00
Matthias Clasen
30f55c4d07 Remove a redundant vfunc
PangoRenderer has a perfectly adequate default
implementation of draw_glyphs, no need to duplicate that.
2019-07-23 23:28:24 -04:00
Ryan Westlund
f00d964f4f Add nullable annotation to combo_box_text_get_active_text 2019-07-23 22:59:35 -04:00
Matthias Clasen
d2920c501d Merge branch 'blink-later' into 'master'
Blink later

See merge request GNOME/gtk!1011
2019-07-24 02:05:32 +00:00
Matthias Clasen
af528b08dc Merge branch 'error-nodes' into 'master'
Render error underlines as render nodes

See merge request GNOME/gtk!1009
2019-07-24 01:39:37 +00:00
Matthias Clasen
a628907891 textview: Defer cursor blinking on input
We were not calling the right cursor functions
in the commit handler.
2019-07-23 21:18:03 -04:00
Matthias Clasen
19ad4d67ef textview: Delay initial cursor blinking
These changes follow the same changes for
gtktext.c in the previous commit.
2019-07-23 21:17:05 -04:00
Matthias Clasen
a4e427b44a text: Delay initial cursor blinking
We used to have a solid cursor for 2/3 of the cycle,
now we start fading after 1/4th. To make up for it,
add half a cycle of delay.
2019-07-23 21:08:47 -04:00
Matthias Clasen
5b94e3c2f2 Merge branch 'wip/chergert/refcount-line-display' into 'master'
make GtkTextLineDisplay ref counted

See merge request GNOME/gtk!1010
2019-07-23 22:44:59 +00:00
Matthias Clasen
3278e9ab6c Render error underlines as render nodes
Use a sequence of transformed squares,
instead of a cairo node. The drawing is not
identical to the previous code, but reasonably
close.
2019-07-23 18:31:39 -04:00
Christian Hergert
02d8e95b73 textlayout: remove use of gtk_text_layout_free_line_display
Now that these are reference counted, we no longer need to use
the variant requiring access to the GtkTextLayout.
2019-07-23 14:59:40 -07:00
Christian Hergert
e0b9b51e9f textlayout: make GtkTextLineDisplay reference counted
This makes GtkTextLineDisplay use GRcBox instead of g_slice_*
directly. By using reference counting for this structure, we
can ensure that we hold an extra ref for one_display_cache as
well as caching additional GtkTextLineDisplay for the visible
range in the future.
2019-07-23 14:52:14 -07:00
Matthias Clasen
fb06b7fa94 text: Remove an outdated comment 2019-07-23 15:14:38 -04:00
Matthias Clasen
7b451678f5 fix the build 2019-07-23 14:26:32 -04:00
Piotr Drąg
3be9e819d6 Update POTFILES.in 2019-07-23 19:47:43 +02:00
Matthias Clasen
758c54eab8 text: Fix incomplete invalidation
When a style change affects the text, we need to
clear the cached content, in order to pick up the
new text style.
2019-07-23 10:41:52 -04:00
Matthias Clasen
c39cc15573 text view: Fix incomplete invalidation
Update the cached text style when a css change affects
content or background. This fixes text views drawing
black-on-dark when switching to the dark theme.
2019-07-23 10:41:43 -04:00
Jordi Mas
8999bb0b78 Update Catalan translation 2019-07-22 11:06:27 +02:00
Matthias Clasen
7a81b7c7be Merge branch 'wip/chergert/fix-textlayout-bounds' into 'master'
textlayout: fix bounds for clipping

See merge request GNOME/gtk!1006
2019-07-22 01:53:17 +00:00
Christian Hergert
e475d4bdc5 textlayout: fix bounds for clipping
This should match gtk_snapshot_append_layout(), which means that we expect the
bounds to be rooted at 0, 0.
2019-07-21 18:21:04 -07:00
Matthias Clasen
980a6a20b1 Merge branch 'wip/textview' into 'master'
textview: port GtkTextView to GskPangoRenderer

See merge request GNOME/gtk!1005
2019-07-21 23:10:41 +00:00
Matthias Clasen
064ad42432 text view: Smooth cursor blinking
Fade the text cursor in and out, instead
of abruptly turning it on and off.
2019-07-21 16:03:49 -07:00
Christian Hergert
4ff9163c47 textview: port GtkTextView to GskPangoRenderer
This removes the use of GtkTextDisplay (a PangoRenderer) to use
the GskPangoRender which generates render nodes. Part of this means
improving the GskPangoRenderer to support the necessary features for
displaying a GtkTextView.

Primarily, this is a merging of GtkTextDisplay features into
GskPangoRender. Additionally, GtkTextDisplay was removed to allow for
gtk_text_layout_snapshot() to be implemented elsewhere.
2019-07-21 16:03:45 -07:00
Matthias Clasen
45ebe47d94 textview: Stop exporting private apis
These headers are no longer 'semi-public, but private
and uninstalled, so exporting these functions does
not do any good.
2019-07-21 13:26:40 -07:00
Matthias Clasen
2803bd93ce gsk: Fix a crash in gsk_render_node_diff
The only thing worse than freeing the same
cairo region twice is freeing it three times.
2019-07-21 13:18:58 -07:00
Matthias Clasen
51161fb0d6 text: Smooth cursor blinking
Fade the text cursor in and out, instead
of abruptly turning it on and off.
2019-07-21 11:35:13 -07:00
Matthias Clasen
63fd97749c Adwaita: Fix entry block cursors 2019-07-21 11:35:04 -07:00
Asier Sarasua Garmendia
f2d736d2cc Update Basque translation 2019-07-21 18:02:07 +00:00
Serdar Sağlam
9b9a656e54 Update Turkish translation 2019-07-21 14:15:15 +00:00
Timm Bäder
8f734b01b2 window: Plug a GList leak
We need to free the GList manually when using g_list_remove_link().
2019-07-21 12:45:10 +02:00
Timm Bäder
69250371b0 gtk.supp: Add glXQueryServerString exceptions 2019-07-21 12:45:10 +02:00
Timm Bäder
731613d70b gl renderer: Remove leftover modelview matrix
We use a GskTransform there nowadays.
2019-07-21 12:45:10 +02:00
Timm Bäder
5f21c45f75 Revert "gl renderer: ops_set_modelview is (transfer full)"
This reverts commit e904c49e8a.

This breaks HiDPI setups, i.e. setups where the call to
ops_set_modelview does not end up with a NULL transform.
2019-07-21 12:45:10 +02:00
Timm Bäder
8beea4d958 window: Merge some functions into their only callers
So it's clear we only add or remove the pointerfocus-es in
_update_pointer_focus.
2019-07-21 11:06:24 +02:00
Timm Bäder
1583200e24 cellrenderertext: Remove some unnecessary NULL checks 2019-07-21 10:26:00 +02:00
Timm Bäder
03fa8ed259 cellrenderertext: Don't unnecessarily ref a layout
We never pass a NULL layout to get_size().
2019-07-21 10:22:05 +02:00
Timm Bäder
0bd939624e textlayout: Remove some outdated comments
These two members have been commented out for 19 years.
2019-07-21 10:02:54 +02:00
Timm Bäder
b658a1a8e3 entry: Measure icons again
This was previously removed because it changes the minimum and natural
size of the entry when the icons are shown/hidden at runtime. Just not
measuring them does not work however, so reintroduce this.
2019-07-21 09:58:08 +02:00
Timm Bäder
7eae9d115c placesview: Make "Other Locations" search case-insensitive
It's just weird to search for "c" and not find the list item labelled
"Computer".
2019-07-21 09:51:54 +02:00
Timm Bäder
2ca56d4c4c linedisplay: Save paragraph bg color inline
No need to allocate this separately.
2019-07-21 09:47:09 +02:00
Timm Bäder
f6d7967e96 gtk.supp: Add a pixman_image_composite32 exception 2019-07-21 09:13:24 +02:00
Timm Bäder
9bddc0ff85 gtk.supp: add a FcDefaultSubstitute exception 2019-07-21 09:07:27 +02:00
Timm Bäder
6e47ebe030 rendernodeparser: Fix a memory leak when parsing glyphs 2019-07-21 09:06:50 +02:00
Timm Bäder
9728dabf12 rendernodeparser: Fix a memory leak when parsing textures 2019-07-21 09:06:29 +02:00
Timm Bäder
e904c49e8a gl renderer: ops_set_modelview is (transfer full)
regarding the passed modelview matrix
2019-07-21 09:06:10 +02:00
Timm Bäder
27ddd39d69 gl renderer: Pull out code from a loop
Does not not actually depend on anything done inside the loop.
2019-07-21 08:39:25 +02:00
Goran Vidović
86e907b088 Update Croatian translation 2019-07-19 21:29:56 +00:00
Goran Vidović
8b46538af9 Update Croatian translation 2019-07-19 21:20:13 +00:00
Timm Bäder
5910a28aa5 gl renderer: Replace a redundant function call
We're already getting the radius from the node above.
2019-07-19 18:14:50 +02:00
Timm Bäder
3935027880 filechooserwidget: Fold function into only caller 2019-07-19 18:14:50 +02:00
Timm Bäder
8665828d7f filechooserwidget: Don't emit default-size-changed() in unroot()
It doesn't make much sense to assume the default size has changed just
because the widget has been unrooted.
2019-07-19 18:14:50 +02:00
Timm Bäder
a8b559e99f filechooser: Remove SETTINGS_KEY_WINDOW_POSITION
Now unused.
2019-07-19 18:14:50 +02:00
Timm Bäder
5674a3db46 filechooserwidget: Don't look at saved window position
We don't save it anymore so no need to look at it here.
2019-07-19 18:14:49 +02:00
Timm Bäder
dd3acc9014 filechooserdialog: Stop using gtk_window_get_position() 2019-07-19 18:14:49 +02:00
Timm Bäder
a9364bc053 Revert "file chooser: Stop using gtk_window_get_position"
This reverts commit 2ed533c3e1.

This also made the filechooser dialog not save the window size anymore,
which does not depend on the gtk_window_get_position() removal.
2019-07-19 18:14:49 +02:00
Timm Bäder
59313e1459 gtkfilechooserwidget: Temporarily disable revealer transitions...
... when going between recent and browse. It just looks weird to have
this transition while the treeview model is just cleared/repopulated
without any transition.
2019-07-19 18:14:49 +02:00
Timm Bäder
3e54d374de placessidebar: Remove sidebar border again 2019-07-19 18:14:49 +02:00
Christoph Reiter
9856218073 Merge branch 'tests-no-box-packing' into 'master'
testsuite: Remove dangling references to box-packing tests

See merge request GNOME/gtk!997
2019-07-18 19:32:19 +00:00
segfault
97cdf87350 gtkmountoperation: Add TCRYPT options to the ask-password dialog 2019-07-18 20:06:20 +02:00
Emmanuele Bassi
d8f91e7df9 Merge branch 'pc-libs-private' into 'master'
gtk4.pc: Move third-party libraries from Libs to Libs.private

See merge request GNOME/gtk!998
2019-07-18 10:31:19 +00:00
Emmanuele Bassi
91d4e2b3e3 Merge branch 'gtk-4-support-tcrypt-with-proxy-handler' into 'master'
gtkmountoperation: Support TCRYPT options when using proxy handler

See merge request GNOME/gtk!245
2019-07-18 10:11:12 +00:00
segfault
e5cccbf5a0 gtkmountoperation: Support TCRYPT options when using proxy handler
GMountOperation now supports options to unlock TCRYPT volumes. This
patch sets these options if they are returned by AskPassword() of a
GtkMountOperationHandlerProxy.
2019-07-18 11:41:45 +02:00
Simon McVittie
5cfe9ab603 testsuite: Remove dangling references to box-packing tests
These were removed in commit c47abb5f, before 3.96.0.

Signed-off-by: Simon McVittie <smcv@debian.org>
2019-07-18 09:26:07 +01:00
Simon McVittie
01a6bbdc73 gtk4.pc: Move third-party libraries from Libs to Libs.private
This avoids "overlinking". These libraries are an implementation detail
of particular backends, so they only need to appear on library consumers'
linker command-lines if the dependency cannot be picked up from the
shared library automatically (when linking statically, or when building
on a deficient OS that doesn't support transitive dependencies between
shared libraries, in which case pkg-config should be built with
--enable-indirect-deps).

Signed-off-by: Simon McVittie <smcv@debian.org>
2019-07-18 09:24:41 +01:00
Timm Bäder
24a4063645 scrollbar: Use a box layout
Makes a lot more sense than the intermediate box just for its layout.
2019-07-15 07:52:42 +02:00
Timm Bäder
4f11bbc59b text: Don't leak emoji chooser 2019-07-15 06:56:19 +02:00
Timm Bäder
9ceb41f9a4 menu: Fix an uninitialized value
If the menu does not have any children, we'd otherwise end up calling
g_object_ref() on an uninitialized value.
2019-07-15 06:43:25 +02:00
Timm Bäder
831309eed2 progressbar: Use box layout
Instead of the custom layouting we did before.
2019-07-15 06:38:51 +02:00
Timm Bäder
4bb4a98493 text: Move some locals into the closest scope 2019-07-15 05:38:25 +02:00
Timm Bäder
70b0f712ad text: Remove some useless casts 2019-07-15 05:19:02 +02:00
Timm Bäder
c6e9372ba3 text: Move some locals into the closest scope 2019-07-15 05:17:46 +02:00
Jordi Mas
13b055ab2d Update Catalan translation 2019-07-14 11:25:12 +02:00
Timm Bäder
38f4a7708e Remove some dead assignments 2019-07-14 10:08:04 +02:00
Timm Bäder
6abcd8d013 Adwaita: Add fontbutton spacing back 2019-07-14 10:08:04 +02:00
Timm Bäder
37906a2200 adwaita: Remove a dead rule
GtkFileChooserButtons are called "filechooserbutton" these days, not
button.file
2019-07-14 10:08:04 +02:00
Timm Bäder
b9b5072668 gl renderer: Fix opacity nodes with overlapping child nodes 2019-07-14 10:08:04 +02:00
Aurimas Černius
459edfa77b Updated Lithuanian translation 2019-07-13 18:28:21 +03:00
Timm Bäder
92a79d3f96 popover: Fix a broken cast
The widget passed here is priv->relative_to, not the popover.
2019-07-13 17:06:22 +02:00
Timm Bäder
984dff54ab rendernodeparser: fix typo 2019-07-13 11:12:47 +02:00
Timm Bäder
1866aa93e3 fishbowl: Plug a small leak 2019-07-13 10:10:17 +02:00
Timm Bäder
2884691740 picture: Unref previous paintable
We were leaking all of them.
2019-07-13 09:38:28 +02:00
Timm Bäder
b8549a142e suppression file: Add glReadPixels mesa exception 2019-07-13 09:38:14 +02:00
Timm Bäder
0f3ca349e7 node editor: Manually unrealize all created renderers
This has not been a problem before since we were leaking them.
2019-07-13 09:37:47 +02:00
Timm Bäder
a13d6bbbdf Merge branch 'fix-issue-2014-gtk4' into 'master'
Fix a string leak in gtkemojicompletion.c [gtk4]

Closes #2014

See merge request GNOME/gtk!993
2019-07-12 09:59:38 +00:00
Luca Bacci
d15dc6f90b Fix a string leak
Fixes #2014
2019-07-12 08:43:44 +00:00
Timm Bäder
58e6c277b0 fpsoverlay: Fix fps overlay position 2019-07-10 18:34:16 +02:00
Matthias Clasen
1d29d44ddb Merge branch 'wip/baedert/accelmap' into 'master'
AccelMap: Sort accels before iterating over them in foreach()

See merge request GNOME/gtk!980
2019-07-09 19:39:58 +00:00
Matthias Clasen
bda3c6c084 Merge branch 'wip/baedert/for-master' into 'master'
Improve the valgrind experience

See merge request GNOME/gtk!984
2019-07-09 19:39:13 +00:00
Kukuh Syafaat
159913be2f Update Indonesian translation 2019-07-09 07:56:21 +00:00
Asier Sarasua Garmendia
b05d1676d3 Update Basque translation 2019-07-08 20:19:10 +00:00
Asier Sarasua Garmendia
0b21ed0c7a Update Basque translation 2019-07-08 20:14:08 +00:00
Asier Sarasua Garmendia
564a92830b Update Basque translation 2019-07-08 19:18:08 +00:00
Chun-wei Fan
a20fd5e14e demos/constraint-editor: Fix linking on MSVC builds
We must apply the /entry:mainCRTStartup linker flag in order to link GTK
apps in pure GUI form.  This follows what is done in demos/gtk-demo,
etc.
2019-07-08 18:37:27 +08:00
Timm Bäder
138986f064 Merge branch 'ui-enum-values' into 'master'
Change the few examples that use a full GTK_ enum value in .ui files.

See merge request GNOME/gtk!987
2019-07-08 07:14:48 +00:00
Timm Bäder
f286c99338 Merge branch 'gltexsubimage2d' into 'master'
use glTexSubImage2D instead of glTextureSubImage2D

Closes #2005

See merge request GNOME/gtk!986
2019-07-08 07:14:13 +00:00
Timm Bäder
ea48d1de5e Merge branch 'glsl-float-literals' into 'master'
glsl: use float literals

See merge request GNOME/gtk!985
2019-07-08 07:10:41 +00:00
Robert Ancell
dbd2a81501 Change the few examples that use a full GTK_ enum value in .ui files.
Lowercase versions work just as well and are much more readable.
2019-07-08 15:52:28 +12:00
Piotr Drąg
be6ec8f50b Update Polish translation 2019-07-07 13:22:10 +02:00
Timm Bäder
264d4bada6 widget: Remove queue_resize_no_redraw
We always invalidate the widget in size_allocate() anyway.
2019-07-07 07:43:08 +02:00
Timm Bäder
633172fd66 widget: Make queue_compute_expand() private
Nobody needs to call this anymore.
2019-07-07 07:36:29 +02:00
Timm Bäder
042f7d117f compare-render: Don't unref an invalid GFile
We already unref it when the g_file_make_directory_with_parents fails.
2019-07-07 07:24:00 +02:00
Timm Bäder
b062594ae6 gl renderer: Properly clean up program state transforms 2019-07-07 07:24:00 +02:00
Timm Bäder
95f30fee87 iconhelper: Try to avoid some save/restore calls
GtkImage already does something similar so we often end up with 0/0
here. Avoid the save()/restore() calls in GtkSnapshot in that case.
2019-07-07 07:24:00 +02:00
Timm Bäder
dbc49e7742 transform: Fix identity transform fast paths
Returning an extra ref will cause leaks later.
2019-07-07 07:24:00 +02:00
Timm Bäder
449c96ffb3 widget: Unref previous transform 2019-07-07 07:24:00 +02:00
Timm Bäder
1459ca2c26 widget factory: Plug a memory leak 2019-07-07 07:24:00 +02:00
Timm Bäder
4123c85021 actionmuxer: Plug a memory leak 2019-07-07 07:24:00 +02:00
Timm Bäder
d1c37c41d9 Add a gtk valgrind suppression file
Not ideal but otherwise I get 30k line output from valgrind when just
running the widget factory. It's mostly mesa but still.
2019-07-07 07:23:57 +02:00
Elias Aebi
ea6d3f589f use glTexSubImage2D instead of glTextureSubImage2D 2019-07-06 16:23:21 +02:00
Elias Aebi
1e6120e776 glsl: use float literals 2019-07-06 14:42:08 +02:00
Timm Bäder
a77f8e886b cssprovider: Fix a memory leak in load_internal
We create a new GBytes but never unref it.
2019-07-06 09:50:07 +02:00
Benjamin Otte
96b782c026 x11: Make sure stream stays alive long enough
When unreffing the stream from a different thread, the close function
will schedule its cleanup asynchornously in the main thread.
We need to make sure the stream object stays alive for as long as
that hasn't happened, so ref() it.

Fixes #2003
2019-07-05 21:17:00 +02:00
Timm Bäder
6455a54f6c Merge branch 'header-custom-title-valign' into 'master'
headerbar: Don't change the custom title's valign

See merge request GNOME/gtk!981
2019-07-04 12:45:13 +00:00
Adrien Plazas
3bae6fa1c7 headerbar: Don't change the custom title's valign
This allows custom titles to use the vertical alignment of their choice
without having to set it manually after it has been added to the header
bar, hence allowing them to define their preferred alignment from a UI
template.

This is useful for widgets like the view switcher which requires filling
the header bar's whole height.
2019-07-04 13:03:37 +02:00
Timm Bäder
68f19a8e6a accelmap: Sort accels before interating over them in foreach() 2019-07-04 08:35:42 +02:00
Timm Bäder
12ebbd1b24 accelmap: Avoid a confusing goto 2019-07-04 08:35:34 +02:00
Emmanuele Bassi
9b7bda6137 ci: Comment job, not just the stage
GitLab doesn't like it when we keep a job but disable the stage.
2019-07-03 17:57:27 +01:00
Emmanuele Bassi
1b4ed58331 ci: Disable deploy jobs
The version of gtk-doc in our CI image is not new enough to cope with
the fact that GTK lost container properties.
2019-07-03 17:54:32 +01:00
Benjamin Otte
b2868d7218 Merge branch 'wip/frame-clock-consumers' into 'master'
Frame clock consumers

See merge request GNOME/gtk!971
2019-07-03 16:21:32 +00:00
Emmanuele Bassi
bdc8f9dccf Merge branch 'layout-manager-ref' into 'master'
widget: Don't lose a layout manager ref

See merge request GNOME/gtk!977
2019-07-03 13:25:44 +00:00
Matthias Clasen
9768f35931 widget: Don't lose a layout manager ref
gtk_widget_set_layout_manager is transfer-full,
so we must give it a new reference from set_property
to implement object property semantics properly.
2019-07-03 09:18:41 -04:00
Daniel Mustieles
19a4ee031d Updated Spanish translation 2019-07-03 11:45:12 +02:00
Jonas Ådahl
a7ee1b4e85 gdksurface: Make all surfaces listen to the frame clock signals
Instead of the toplevel driving popups, have the popups listen to the
frame clock themselves. Otherwise, if the toplevel for some reason isn't
drawn by the compositor and stops drawing new frames, popups wouldn't
get painted either.
2019-07-03 11:42:28 +02:00
Jonas Ådahl
5db079b052 gdk/frameclock: Make surfaces inhibit freeze
To make a frame clock tick as long as any of the associated surfaces
expect to receive ticks, make the surfaces inhibit freezing the clock,
instead of directly tell the frame clock to freeze itself.

This makes it so that as long as any surface using a certain frame clock
is not frozen (e.g. just received a frame event from the display
server), the frame clock will not be frozen.

With this, the frame clock is initiated as frozen, and won't be thawed
until any surface inhibits freeze. It will be frozen again, when every
surface has that previously inhibited freeze uninhibited freeze.
2019-07-03 11:42:28 +02:00
Jonas Ådahl
a2ff6af4b3 tests: Add back testpopupat
It's still useful for testing menus. Fixed the .ui file by removing a
property that no longer exists.

This effectively reverts commit
84d2150077.
2019-07-03 11:42:28 +02:00
Jonas Ådahl
f66e764855 menu: Remove unused variable 2019-07-03 11:42:28 +02:00
Mohammed Sadiq
a8c23d06ac constraint: Fix property name typo in doc 2019-07-03 09:31:39 +05:30
Piotr Drąg
36b4cd4bfc Update POTFILES.in and POTFILES.skip 2019-07-02 19:02:36 +02:00
Matej Urbančič
46c59e3c3d Updated Slovenian translation 2019-07-02 18:51:55 +02:00
Matthias Clasen
b5aee936a9 Merge branch 'constraint-list-model' into 'master'
Constraint list models

See merge request GNOME/gtk!975
2019-07-02 14:18:42 +00:00
Matthias Clasen
aa8687316f constraint editor: Implement loading
Allow to reread the ui builder files we write out.
Just barely.
2019-07-02 10:03:48 -04:00
Matthias Clasen
5a3cf5a194 constraints editor: Stop naming constraints
We don't have a field for the name in ui files,
so stop naming constraints.
2019-07-02 10:03:48 -04:00
Matthias Clasen
c5e1b00994 constraint editor: Implement saving
Save to a ui file.
2019-07-02 10:03:48 -04:00
Matthias Clasen
377f0c1a0a constraint editor: Use name properties 2019-07-02 10:03:48 -04:00
Matthias Clasen
a442e6e8de constraint editor: Use the list models
Instead of handrolling our own list models,
use the ones provided by GtkConstraintLayout.
2019-07-02 10:03:48 -04:00
Matthias Clasen
274c47e5ba constraint layout: Provide list models
Provide list models for the constraints and guides,
so we can show them in the inspector, and use them
in e.g. the constraints editor.
2019-07-02 10:03:48 -04:00
Matthias Clasen
b2f15a622d Merge branch 'wip/ebassi/constraint-layout' into 'master'
Add constraint-based layout manager

Closes #1090

See merge request GNOME/gtk!973
2019-07-02 14:01:01 +00:00
Emmanuele Bassi
04aaf02881 docs: Add more private headers to the list
The various GtkConstraint private API should not be scanned for
documentation.
2019-07-02 09:48:17 +01:00
Emmanuele Bassi
d5f8e1bf29 docs: Fix typo in function name 2019-07-02 09:44:48 +01:00
Daniel Boles
33bd7051f2 widget-factory: Use correct StyleProvider priority
We are an application, not a user.

cherry-pick of !974
2019-07-02 09:09:47 +01:00
Matthias Clasen
61345b3216 Merge branch 'option-names' into 'master'
meson: Rename documentation option to gtk_doc

See merge request GNOME/gtk!972
2019-07-02 01:28:43 +00:00
Benjamin Otte
129691f3a6 flattenlistmodeL: Compute items-changed position properly
The code previously forgot to include the left child of the model's
node. Which of course only happened if that child wasn't NULL, which is
a common case.

Found and test provided by Matthias Clasen.
2019-07-02 02:53:00 +02:00
Matthias Clasen
4eaf860e86 meson: Rename documentation option to gtk_doc
This name is what most of the stack is using.
Lets follow along, even though it is (imo)
uglier.
2019-07-01 20:16:37 -04:00
Christoph Reiter
72814c54a8 meson: cups: use cups-config for looking up cups
We were looking for the cups headers and the cups lib in the default locations
which for example breaks with OpenBSD where the cups headers are under /usr/local/include/

Instead just use the "cups" dependency type from meson which internally uses cups-config.

See #1967

Ported to master from !963
2019-07-01 21:52:06 +02:00
Christoph Reiter
4d4e02c9d0 build/cups: remove checks for httpGetAuthString and http_t.authstring
httpGetAuthString() was added with cups 1.3 and we depend on a newer version
now. The direct field access was a fallback in case httpGetAuthString()
was missing, so this can also be dropped.

Ported to master from !938
2019-07-01 21:34:44 +02:00
Emmanuele Bassi
8ab609e4e7 Add custom parser for guides defined in GtkBuilder UI files
Like we describe constraints, we can also define guides.
2019-07-01 19:22:48 +01:00
Emmanuele Bassi
6bc156c237 Implement GtkBuildable for GtkConstraintLayout
Using GtkBuildable we can provide a custom parser for reading
constraints defined in a GtkBuilder UI file.
2019-07-01 18:03:20 +01:00
Emmanuele Bassi
b435dc4366 Use the right GValue getter for GtkConstraintGuide:strength
The property is defined as an enum.

This fixes the defaultvalue and notify tests.
2019-07-01 18:02:19 +01:00
Emmanuele Bassi
4dd1de4129 Use explicit values for constraint strength
Instead of playing games with mapping negative symbolic values to
positive ones, let's use the appropriate constants everywhere. This
allows us to use:

        GTK_CONSTRAINT_STRENGTH_WEAK * 2

Or

        GTK_CONSTRAINT_STRENGTH_STRONG + 1

In code using the public API.

We also store the strength values as integers, so we can compare them
properly, and only turn them into doubles when they are inserted into
the solver, just like every other variable.
2019-07-01 12:39:24 +01:00
Matthias Clasen
48e6cd4255 constraint editor: Allow dragging children
We add a weak constraint for the position
and update it as the widget is dragged.
2019-07-01 04:24:26 +00:00
Matthias Clasen
658397fad0 Documentation fixes
Make sure all types show up in the docs,
and misc other improvements.
2019-07-01 03:17:58 +00:00
Matthias Clasen
670fc5bb94 constraint editor: Enable max size for guide
Also, use the apis we have now, and make the
spin buttons display 'unset' values as such.
2019-07-01 02:23:39 +00:00
Matthias Clasen
b224df8109 constraint layout: go back to keeping constraints
We want to minimize changes to the solver, so
keep the size constraints around and only update
them when the size changes.
2019-07-01 01:54:57 +00:00
Matthias Clasen
c88e7c180d constraint layout: Use stronger force for min size
We want our edit constraint to be strong enough to
overpower nat. size constraint, therefore use STRONG * 2.
2019-07-01 01:49:20 +00:00
Emmanuele Bassi
2aabd64f1a Fix warnings from the introspection scanner
The name of the arguments of the functions must match the name of the
arguments in the documentation stanza.
2019-07-01 01:13:00 +01:00
Emmanuele Bassi
7990b24287 Add gtkconstraintguide.h to the public headers
It needs to be introspected and installed.
2019-07-01 01:12:25 +01:00
Emmanuele Bassi
c76c1a46e4 Remove specialised API from GtkConstraint
Thet widget-based API for constraint target and source properties is
unused, and not really necessary.
2019-07-01 01:05:04 +01:00
Emmanuele Bassi
68fed63eac Add missing documentation for GtkConstraint 2019-07-01 01:02:56 +01:00
Emmanuele Bassi
46403bac12 docs: Add GtkConstraint and friends to the API reference 2019-07-01 00:49:20 +01:00
Emmanuele Bassi
74c626f835 Document GtkConstraintGuide 2019-07-01 00:48:59 +01:00
Emmanuele Bassi
d45a662679 Move the VFL error domain to a public header
Since the public API will use it to fill out GErrors, it needs to be
publicly available.
2019-07-01 00:48:48 +01:00
Matthias Clasen
f6019f1a16 Merge branch 'gbsneto/fix-popover-dark-theme' into 'master'
Fix GtkPopoverMenu in dark theme

See merge request GNOME/gtk!970
2019-06-30 23:17:40 +00:00
Matthias Clasen
514de0b91a Add a constraint editor demo
This is an initial cut at providing a tool
for interactive exploration of constraints.
2019-07-01 00:10:11 +01:00
Emmanuele Bassi
9a463056d0 constraint layout: Notice when guides change
We need to queue a resize here.
2019-07-01 00:10:11 +01:00
Matthias Clasen
035baa092c Mark the layout as changed
We should mark the layout as changed when
constraints are added or removed.
2019-07-01 00:10:11 +01:00
Matthias Clasen
499738c903 constraint guide: Avoid redundant constraints
There is no point in creating a stay for nat
size when min == max. And no point in a constraint
for <= G_MAXINT either.
2019-07-01 00:10:11 +01:00
Matthias Clasen
f2d7433bf6 constraint guide: Fix initial property values
This was overlooked when the max-width/max-height/
strength properties were added.
2019-07-01 00:10:11 +01:00
Matthias Clasen
405121bccc constraint solver: Use GTK_NOTE
Allow using GTK_DEBUG=constraints to get debug
output from the constraints solver.
2019-07-01 00:10:11 +01:00
Matthias Clasen
cb96b34315 solver: Add private statistics api
No point in keeping these counters without
a way to show them.
2019-07-01 00:10:11 +01:00
Matthias Clasen
9edf6fb6cb constraint layout: Dont reset constraints in allocate
If trust our allocation algorithm, this can never
trigger (and in fact, it never does).
2019-07-01 00:10:11 +01:00
Matthias Clasen
e3c4fb67ca constraints: Add some internal apis
Checking if a set is empty or a singleton can
be done more efficiently than determining its size.
2019-07-01 00:10:11 +01:00
Matthias Clasen
a9dfca04e4 constraint guide: Make strength tweakable
The strength for the natural width can be used
as a tie-breaker to make instable systems behave
in a more predictable way. This can be seen
in the simple constraints demo in gtk-demo.
2019-07-01 00:10:11 +01:00
Matthias Clasen
71b52f485e constraints demo: Update comments 2019-07-01 00:10:11 +01:00
Matthias Clasen
f62fc4e2f2 constraint layout: freeze/thaw on mass ops
In measure and allocate we are potentially
changing quite a few constraints. Don't
optimize at every step.
2019-07-01 00:10:11 +01:00
Matthias Clasen
511e2b435e constraints: Use better data structures
Use a GSequence for GtkVariableSet, to avoid
quadratic behavior.
2019-07-01 00:10:11 +01:00
Matthias Clasen
3f36340921 constraint layout: Measure min/nat size separately
Only constraint the opposite direction if we
actually have a for_size, and measure natural
size after removing the edit constraints. With
these changes, the test that compares constraint
layout to grid layout passes.
2019-07-01 00:10:11 +01:00
Matthias Clasen
b1f0f4478e constraint layout: Use stays for natural size
It makes more sense to treat the natural size
of both children and guides as stays, since
we want to meet these values as closely as we
can, under the circumstances.
2019-07-01 00:10:11 +01:00
Matthias Clasen
90f8dcc5e1 constraint layout: Add debug output for guides
Print out the allocation we end up giving to
guides. This helps in making sense of the
allocations of the child widgets that these
guides relate to.
2019-07-01 00:10:11 +01:00
Matthias Clasen
5a019bfccd constraints demo: Give space a name
Lets call it 'space'.
2019-07-01 00:10:11 +01:00
Matthias Clasen
b39a5fe5dc constraint guide: Add a name property
We need to be able to print meaningful debug messages
regarding these objects, and eventually present them
in the inspector too.
2019-07-01 00:10:11 +01:00
Matthias Clasen
c7ef8411bd constraint guide: Shorten names
Now that this is its own source file,
no need for these prefixes anymore.
2019-07-01 00:10:11 +01:00
Matthias Clasen
dab8a8b5c5 constraint layout: Measure more correctly
Set up all constraints for minimum + natural
width + height when measuring, regardless
of the orientation we're measuring. Anything
else will lead to incorrect answers when
there are constraints that cut across
dimensions.
2019-07-01 00:10:11 +01:00
Matthias Clasen
8b9c5e3a04 solver: Fix a copy/paste error 2019-07-01 00:10:11 +01:00
Matthias Clasen
3d3a672deb constraint solver: Fix repeat suggestions
We were not storing the previous value, causing
the first two suggestions to work, but not later
ones.

Fixes the test added in the previous commit.
2019-07-01 00:10:11 +01:00
Matthias Clasen
2f97134a08 Amend a constraint solver test
Make the 'repeat edit' test make more than to
suggestions in a single edit phase. It turns out
that this does not work, whereas just doing
two in a row does.
2019-07-01 00:10:11 +01:00
Matthias Clasen
47237d32eb demo: Use constraint guide api
Use proper api to create and set up
the guide, and also try max-width.
2019-07-01 00:10:11 +01:00
Matthias Clasen
139a59cae3 Flesh out GtkConstraintGuide
This commit moves GtkConstraintGuide into its own
source files to avoid gtkconstraintlayout.c turning
too messy, adds max size properties and implements
getters and setters.
2019-07-01 00:10:11 +01:00
Matthias Clasen
60fb9092fe Drop an indirection
This struct is not really useful for just
a single hash table, and it gets in the way
of moving the guide code to its own file.
2019-07-01 00:10:11 +01:00
Matthias Clasen
61b4febbaf Detach guides on unroot
We don't want to leave constraints behind.
2019-07-01 00:10:11 +01:00
Matthias Clasen
4f4ba8c4f6 Simplify the guide implementation
Store the values and constraints in
arrays, to facilitate treating them
uniformly.
2019-07-01 00:10:11 +01:00
Emmanuele Bassi
651adbfb39 Return the list of constraints added via VFL description
Otherwise it's impossible to remove them.
2019-07-01 00:10:11 +01:00
Emmanuele Bassi
3204347bb0 Add method to remove all constraints from a layout 2019-07-01 00:10:11 +01:00
Georges Basile Stavracas Neto
b929846cc1 Adwaita: Also apply $color_menu to popover arrows
So that popovers and arrows are always in agreement of
the background color.
2019-06-30 19:51:51 -03:00
Georges Basile Stavracas Neto
fe65da05be Adwaita: Use $menu_color background in popover.menu
GtkPopoverMenus should mimic menus. Commit d936967b7a introduced
some CSS related to menu popovers, however, it hardcodes 'white'
as the background color. That is problematic for the dark theme.

Use '$menu_color' instead of 'white', since $menu_color both
guarantees menu popovers and menus match, and already handles
different colors for dark and light theme variants.
2019-06-30 19:47:32 -03:00
Emmanuele Bassi
06c825df90 Add a C convenience function for VFL constraints
The dictionary-based function is convenient for language bindings, but C
developers will feel more at home with a variadic arguments list.
2019-06-30 23:42:45 +01:00
Emmanuele Bassi
46430ea85b Add Constraints/VFL demo
Shows how to describe constraints using VFL instead of constructing
objects manually.
2019-06-30 23:42:45 +01:00
Emmanuele Bassi
859c95b435 Allow adding constraints described through VFL 2019-06-30 23:42:45 +01:00
Emmanuele Bassi
5ea8167802 Add VFL parser for constraints
Constraints can be expressed with a compact syntax, called VFL (visual
format language).
2019-06-30 23:42:45 +01:00
Emmanuele Bassi
92d3d55164 Remove GtkConstraintVariable.set_prefix()
The prefix and name are set at construction time.
2019-06-30 23:42:45 +01:00
Matthias Clasen
ba2125d8e1 Add an interactive constraints demo 2019-06-30 23:42:44 +01:00
Matthias Clasen
7c96326c18 Make the constraints demo more interesting
Add a max size to the buttons, to force the
space to open up.
2019-06-30 23:42:44 +01:00
Matthias Clasen
38d353dc1a Add GtkConstraintGuide
This is meant to be a flexible space.
2019-06-30 23:42:44 +01:00
Emmanuele Bassi
7ae04ba36b Use generic pointers for constraint targets
Since GtkWidget implements GtkConstraintTarget, we can omit the explicit
cast, and validate the type at run time.
2019-06-30 23:42:44 +01:00
Matthias Clasen
39c284c490 Redefine constraints with GtkConstraintTarget
This is in preparation for allowing non-widgets
to act as constraint targets.
2019-06-30 23:42:44 +01:00
Matthias Clasen
895e8e25a8 widget: Implement GtkConstraintTarget 2019-06-30 23:42:44 +01:00
Matthias Clasen
04562a76e3 Add GtkConstraintTarget
This is an marker interface that we will
use to accept other things that widgets
in constraints.
2019-06-30 23:42:44 +01:00
Emmanuele Bassi
b6781e06c1 Notify a layout change when adding and removing constraints
Changing the set of constraints should cause a relayout.
2019-06-30 23:42:44 +01:00
Emmanuele Bassi
54104b6676 Fix the opposite size measurement in GtkConstraintLayout
We cannot use the given "for size" when querying our children, because
the constraint layout has no idea about the opposite size of its
children until the layout is complete.

Additionally, we should only suggest an opposite size for the layout if
we have one, instead of suggesting a weak zero size.
2019-06-30 23:42:44 +01:00
Emmanuele Bassi
21450d5f23 Remove size constraints from ConstraintLayoutChild
The size constraints are transient to measurement and allocation, so
they don't really need to be stored inside the GtkLayoutChild subclass
created by a GtkConstraintLayout.
2019-06-30 23:42:44 +01:00
Matthias Clasen
a39bbb2041 constraints: Make internal consistency required
The relations between left, right, width
and top, bottom, height are required for
internal consistency. It doesn't make sense
to ever drop these.

Changing the strength of these relations makes
my systems behave much more stable.
2019-06-30 23:42:44 +01:00
Matthias Clasen
176d9c6baf Add gtk_constraint_layout_remove_constraint
Otherwise, you can't do many interesting things.
2019-06-30 23:42:44 +01:00
Emmanuele Bassi
64afa765c8 Do not release reference on the subject of an expression
We don't own the reference in the first place.
2019-06-30 23:42:44 +01:00
Matthias Clasen
a246d8c926 constraints solver: Avoid critials
When the solver is finalized with existing
constraints, we end up with criticals when
the constraints ref finalize code calls
back into the hash table. Avoid that by
emptying the hash table beforehand.
2019-06-30 23:42:44 +01:00
Matthias Clasen
0531e663ee constraint solver: Fix thawing
There was an obviously wrong precondition here.
2019-06-30 23:42:44 +01:00
Emmanuele Bassi
bd2349c0a0 Do not leak LayoutChild instances
Since the LayoutManager owns the LayoutChild it creates, it's also
responsible for mopping them up.
2019-06-30 23:42:44 +01:00
Emmanuele Bassi
636fbc0f1a Add GtkConstraintLayout demo 2019-06-30 23:42:44 +01:00
Emmanuele Bassi
cdf80f1d65 Add GtkConstraintLayout
A layout manager using GtkConstraintSolver to measure and allocate
children.
2019-06-30 23:42:44 +01:00
Emmanuele Bassi
e7b2c530c5 Propagate rooting and unrooting widgets to layout managers
Layout managers may need to get access to data attached to the root of a
scene graph.
2019-06-30 23:42:44 +01:00
Emmanuele Bassi
e07098da03 window: Create a GtkConstraintSolver
Implement the GtkRoot getter for GtkConstraintSolver.
2019-06-30 23:42:44 +01:00
Emmanuele Bassi
98a21bf498 Assign a GtkConstraintSolver to each GtkRoot
Constraints need to work across different parents, so it's better to
have a single constraint solver per top level.
2019-06-30 23:42:44 +01:00
Emmanuele Bassi
c694dd6049 Move the Root interface to a private header
We don't expect out of tree implementations of GtkRoot, and having the
interface structure private to the GTK code allows us to add virtual
functions involving private types.
2019-06-30 23:42:44 +01:00
Emmanuele Bassi
6b308cd71e Add constraint solver
GtkConstraintSolver is an implementation of the Cassowary constraint
solving algorithm:

  http://constraints.cs.washington.edu/cassowary/

The Cassowary method allows to incrementally solve a tableau of linear
equations, in the form of:

  x = y × coefficient + constant

with different weights, or strengths, applied to each one.

These equations can be used to describe constraints applied to a layout
of UI elements, which allows layout managers using the Cassowary method
to quickly, and efficiently, lay out widgets in complex relations
between themselves and their parent container.
2019-06-30 23:42:44 +01:00
Matthias Clasen
3b6ee32f83 Fix a crash in action muxer destruction
I've seen a crash when the action muxer gets
disposed during widget destroy, and tries to
disconnect from widget signals too late.

There is no real need to disconnect, since the
only time an action muxer is going away is when
its widget is destroyed, so just don't do it.
2019-06-30 18:37:32 +00:00
Timm Bäder
3bc3e140dd transform: Add transform_bounds fast path for 2D_AFFINE transforms
E.g. anything involving a scale. This is important when e.g. scrolling
in the node list in the recorder, which scales every recorded node down
to fit in the list.
2019-06-29 09:49:38 +02:00
Timm Bäder
a6a9853676 Adwaita: Fix popover style
We add the .background class to the popover node now.
2019-06-29 09:06:32 +02:00
Timm Bäder
6b42e5b433 gl renderer: Fix push/pop modelview behavior 2019-06-29 08:57:27 +02:00
Timm Bäder
99c01607f1 gl renderer: Remove some dead code 2019-06-29 08:53:36 +02:00
Timm Bäder
071748592d gl renderer: Don't upload GL textures into the icon cache 2019-06-29 07:15:43 +02:00
Timm Bäder
8dd74eac2e transform: Add skew parsing 2019-06-29 07:15:43 +02:00
Matthias Clasen
f6a2678486 Add another grid layout test
This one will be used for comparison
with constraint layouts.
2019-06-28 19:21:21 +00:00
Matthias Clasen
e28ec2a3eb Some more grid layout tests
Add testcases for spanning children and homogeneity.
2019-06-28 18:07:23 +00:00
Matthias Clasen
c4fd786866 Add a test for the grid layout manager
Test some obvious conditions. This is mainly
to test the waters for more intesting tests
with other layout managers later.
2019-06-28 13:30:16 +00:00
Matthias Clasen
8fa7de5563 grid layout: Fix initial property values
Too bad that we don't cover layout children
in the default value test - it would have
caught this.
2019-06-28 12:42:06 +00:00
Jakub Steiner
9e6b4e82c9 Adwaita: allow flat list row buttons to be flat
- Be more specific about the list row image buttons

Addresses corner case of https://gitlab.gnome.org/GNOME/gtk/issues/1748
2019-06-27 12:15:51 +02:00
Jakub Steiner
4be2e804ae Adwaita: lighten dark switch sliders
- addresses legibility concerns

Fixes https://gitlab.gnome.org/GNOME/gtk/issues/1819
2019-06-27 10:58:18 +02:00
Alex Monday
1056e9976a Adwaita: Apply border-radius to .csd popovers
Fix popover_radius variable doesn't apply to .csd popover.

Closes https://gitlab.gnome.org/GNOME/gtk/issues/1984
2019-06-27 10:40:22 +02:00
Alex Monday
851bb61455 Adwaita: Fix padding/rounding on submenus
- Apply menubar submenu style for .csd submenus;
- Remove child subemenu style (looks like it is inherited
  from a parent).

Closes https://gitlab.gnome.org/GNOME/gtk/issues/1976
2019-06-27 10:31:11 +02:00
Jakub Steiner
3aadc29af4 Adwaita: darken osd background for A:dark
- OSD background color was too close to $bg_color to make out outline

Fixes https://gitlab.gnome.org/GNOME/gtk/issues/1964
2019-06-27 10:30:01 +02:00
Matthias Clasen
3d55b74197 Merge branch 'master' into 'master'
Fix a typo

See merge request GNOME/gtk!960
2019-06-24 19:52:12 +00:00
Hodong Kim
19b1fcfee3 Fix a typo 2019-06-24 18:42:40 +00:00
Daniel Boles
98cfbd3712 ShortcutsSection: Fix tiny grammar-o "in for"→"in" 2019-06-24 18:02:15 +01:00
Ask Hjorth Larsen
112f49b23c Updated Danish translation of gtk-properties 2019-06-24 18:55:47 +02:00
Ask Hjorth Larsen
4d36fdc176 Updated Danish translation of gtk 2019-06-24 18:55:25 +02:00
Matthias Clasen
31d79b07b7 Merge branch 'no-varargs-activate' into 'master'
Add a non-varargs variant of activate_action

See merge request GNOME/gtk!959
2019-06-24 16:10:03 +00:00
Matthias Clasen
2405e2711e Add a non-varargs variant of activate_action
I recently turned gtk_widget_activate_action()
into a varargs function. That is more convenient
from C, but we need a non-varargs variant for
bindings. So add the old API back, under the
name gtk_widget_activate_action_variant(),
with a rename-to annotation.
2019-06-24 15:51:39 +00:00
Emmanuele Bassi
1527407c3d Merge branch 'issue-1961-master' into 'master'
Provide GdkMonitor:connector

See merge request GNOME/gtk!954
2019-06-24 15:13:15 +00:00
Emmanuele Bassi
f524a9315b Set the monitor's connector under X11
Like we do on Wayland.

In this case, we copy it from the same source as the output name,
because it's going to match.
2019-06-24 15:38:36 +01:00
Emmanuele Bassi
a5f22897f9 Relay the xdg_output.name to GdkMonitor
The xdg_output v2 interface has a `name` property that reflects the
output name coming from the compositor.

This is the closest thing we can get to a connector name.
2019-06-24 15:38:36 +01:00
Emmanuele Bassi
03840fb687 Add getter for a monitor connector
The migration from GdkScreen's monitor API to GdkMonitor left out a way
to get the connector's name of a monitor.

While there's no real guarantee coming from the underlying graphics
system that the connector's name is stable, some system components may
use it to uniquely identify a monitor until the next plug in/out event.
2019-06-24 15:38:36 +01:00
Emmanuele Bassi
6e65c16b60 Merge branch 'stack-realign' into 'master'
build: Do not use add_global_flags()

See merge request GNOME/gtk!958
2019-06-24 14:22:18 +00:00
Emmanuele Bassi
23e4d05383 build: Do not use add_global_flags()
It's almost always not what you want.
2019-06-24 15:00:21 +01:00
Daniel Mustieles
489e9e0934 Updated Spanish translation 2019-06-24 09:59:52 +02:00
Matthias Clasen
3acc014499 Make gtk_widget_activate_action better
As a convenience API, this should be easy to use,
so don't expect callers to manually create a
variant, do it for them.

Update all callers.
2019-06-23 22:51:55 +00:00
Matthias Clasen
3ebe30bf32 widget: create parent muxers lazily
We need to create a muxer eagerly for every
widget that has class actions, since those
are otherwise missed in the action lookup
on the muxer side. But otherwise, there is
no reason to create parent muxers aggressively,
as long as we update the parent muxers on
root/unroot.

This reduces the number of muxers we create
in widget-factory from 210 to around 50.
2019-06-23 17:59:41 +00:00
Matthias Clasen
996f011ed8 window: Fix the default value of mnemonics-visible
They aren't visible, so why should the property
be TRUE?
2019-06-23 10:59:17 -04:00
Timm Bäder
0611370a5f Merge branch '362-gtk-fileopen-dialog-need-filetype-mime-sort-option-2_GTK4' into 'master'
GtkFileChooser: add a sortable "Type" column

Closes #362

See merge request GNOME/gtk!874
2019-06-23 07:58:26 +00:00
Matthias Clasen
1be850d806 Add includes back to gtk4.types.in
Without these, gtkdoc-scangobj doesn't work. Who knew!
2019-06-22 21:42:30 -04:00
Matthias Clasen
b903d8ee33 Add another action test
Test that disabled actions aren't activated.
2019-06-23 01:39:34 +00:00
Matthias Clasen
8fd968e5bf action muxer: Don't activate disabled actions
We really shouldn't.
2019-06-23 01:39:26 +00:00
Matthias Clasen
366e8da927 Add another test for action inheritance
This one checks for precedence between
class actions and inserted groups.
2019-06-22 23:30:22 +00:00
Matthias Clasen
203d612afd widget: Clarify docs for action inheritance
Spell out how action inheritance works wrt to prefixes.
2019-06-22 19:17:30 -04:00
Matthias Clasen
135580108a Add a test for action introspection
This checks that gtk_widget_query_action works.
2019-06-22 23:11:49 +00:00
Matthias Clasen
4515604511 Add another test for action inheritance
Check that overlapping prefixes are handled
correctly.
2019-06-22 23:00:42 +00:00
Matthias Clasen
ad4a81e9df action muxer: Change inheritance
Previously, we would not look any further for
an action once we found a match for the prefix,
defining inheritance by groups. Change this to
inheritance for individual actions, since we
are moving towards individual actions as the
main ingredient in GTKs action support.
2019-06-22 22:51:23 +00:00
Matthias Clasen
95e5472ade action muxer: Remove unused api 2019-06-22 22:38:14 +00:00
Matthias Clasen
06ff4a8b6f textview: Stop using action muxer needlessly
This lets us drop some private api.
2019-06-22 22:34:26 +00:00
Matthias Clasen
1f0904d3df widget: Teach query_action about property actions
This might be useful for documentation purposes.
2019-06-22 17:04:01 -04:00
Matthias Clasen
35a88c1440 widget: Rename a function
set_enabled is shorter and more to the point
than enabled_changed, now that we no longer have
a callback to query the state.

Adapt all callers.
2019-06-22 17:03:51 -04:00
Matthias Clasen
d1f4068b94 Replace stateful actions by property actions
The only cases of stateful actions we've seen
so far have been boolean properties, and we
don't really want to add much state handling
API, so lets just go with property actions
for now.

Adapt the only user in GtkText.
2019-06-22 17:03:38 -04:00
Matthias Clasen
7e73da5f73 widget: Add parameter type back to install_action
Adapt all callers.
2019-06-22 16:48:16 -04:00
Nelson Benítez León
c789a39660 GtkFileChooser: add a sortable "Type" column
along with a new 'type-format' setting that allows
to choose the output format for the "Type" column.

The options implemented for this setting are:

'mime' : Output from g_content_type_get_mime_type().

'description' : Output from g_content_type_get_description().

'category' : It uses the corresponding generic icon
  of the mime type to group by categories (aka basic types).

  This produces a more compact output than previous options,
  and allows for type families to be grouped together, so eg.
  after sorting by "Type" column, jpeg and png images will
  be placed together, or the various types of archiver files
  will also be grouped together.

  This format was copied from and currently used by Nautilus
  list view, so we also improve consistency with Nautilus.
  Bugzilla entry for Nautilus implementation is:
  https://bugzilla.gnome.org/show_bug.cgi?id=683722

  The list of type families or categories can be checked on:
  https://developer.gnome.org/icon-naming-spec/#mimetypes

  This 'category' format is set as default.

Issue #362
2019-06-22 13:22:59 -04:00
Matthias Clasen
3c6045e300 css: Fix some doc typos 2019-06-22 09:49:50 -04:00
Matthias Clasen
9389768a17 Add GTK_CSS_PARSER_WARNING_UNIMPLEMENTED
gtk-doc was complaining about it missing,
and it is used in some ifdefed code.
2019-06-22 09:48:34 -04:00
Matthias Clasen
412006ad23 Add owner types for widget actions
This lets us filter out actions from parent classes
when introspecting.
2019-06-22 09:38:30 -04:00
Matthias Clasen
ea456b80da Make actions minimally introspectable
This will let us autogenerate some docs for
actions, in the future.
2019-06-21 22:47:40 -04:00
Matthias Clasen
152eabbaba widget actions: Add an explicit state type
Make the state type part of the API for installing
stateful widget actions. That lets us introspect it.

Update all callers.
2019-06-21 22:47:40 -04:00
Matthias Clasen
9be0b3d76f application: Stop extracting accels from menus
This functionality has been superseded by
gtk_application_set_accels_for_action in GTK3,
and we don't want to carry it forward in GTK4.
2019-06-21 22:47:40 -04:00
Goran Vidović
27644dc573 Update Croatian translation 2019-06-21 23:38:11 +00:00
Goran Vidović
41595cf336 Update Croatian translation 2019-06-21 22:40:38 +00:00
Goran Vidović
8f3fb4109f Update Croatian translation 2019-06-21 22:06:32 +00:00
Goran Vidović
417a70b096 Update Croatian translation 2019-06-21 11:17:40 +00:00
Goran Vidović
6f82fd8b2e Update Croatian translation 2019-06-21 10:49:10 +00:00
Daniel Mustieles
53d43dff46 Updated Spanish translation 2019-06-21 10:04:41 +02:00
Matthias Clasen
3ef8af3be9 Add a test for GtkText actions
Check that the class actions are there and work.
2019-06-21 03:58:21 +00:00
Matthias Clasen
fe6507f875 Add a test for gtk_widget_insert_action_group
This tests that action group inheritance
behaves as expected.
2019-06-21 03:58:13 +00:00
Matthias Clasen
9b0d87c5a7 window: Cosmetics 2019-06-21 02:55:27 +00:00
Matthias Clasen
a515fca63f inspector: Fix actions visibility
We need to always hide the page when setting
an object, otherwise the initial visibility
sticks.
2019-06-20 22:49:22 -04:00
Matthias Clasen
b6baa15e0a inspector: Use event controller names
Use these in the same place we use widget names.
2019-06-20 22:48:42 -04:00
Matthias Clasen
955ae40cd6 event controller: Add a name property
This helps identifying controllers in the inspector.
2019-06-20 22:48:33 -04:00
Matthias Clasen
dee9e40ad3 Build fix 2019-06-20 22:47:35 -04:00
Matthias Clasen
a933a9bc79 Fix initial mnemonic visibility
We were showing mnemonics initially, which is not desired.
2019-06-21 02:38:05 +00:00
Matthias Clasen
6a4a082660 main: Move visible mnemonics handling
No need to special-case this anymore; we can use
a regular event controller in GtkWindow for this.
2019-06-21 02:37:51 +00:00
Matthias Clasen
a7cdcdf92c main: Move visible focus handling
No need to special-case this anymore; we can use
a regular event controller in GtkWindow for this.
2019-06-21 02:37:12 +00:00
Daniel Boles
a7a0a34da1 Overlay: Document overlay children aren't measured
Some users expect that the Overlay will automatically request enough
size for its overlay children as well as its main child. It doesn't,
because it's just a GtkBin. Add a short paragraph pointing that out.

Close https://gitlab.gnome.org/GNOME/gtk/issues/1939
2019-06-20 21:41:59 +01:00
Efstathios Iosifidis
299bd5fa93 Update Greek translation 2019-06-20 20:26:15 +00:00
Efstathios Iosifidis
c25e948375 Update Greek translation 2019-06-20 20:10:21 +00:00
Daniel Boles
a03e531772 FileChooserButton: Document the CSS nodes & class
The only glancing mention of this we had was that GtkButton mentioned it
in passing when discussing how `button` could get contextual classes,
and even that's not relevant in master anymore... so drop it from there.
2019-06-20 20:51:37 +01:00
Daniel Mustieles
1420408858 Updated Spanish translation 2019-06-19 10:10:08 +02:00
Daniel Mustieles
4414e7ec7b Updated Spanish translation 2019-06-19 10:09:03 +02:00
Daniel Boles
217f9ea3b8 ListBox: Document buildable child type placeholder
andyholmes on IRC asked about this and it wasn't documented, so fix that
2019-06-18 21:45:08 +01:00
Daniel Boles
ab7b9d882e Window: Hyperlink to GtkBuildable from its section 2019-06-18 21:45:08 +01:00
Benjamin Otte
4a19bab5b3 gsk: Fix annotations for ref()/unref() 2019-06-18 15:58:49 -04:00
Benjamin Otte
27d6276212 bindings: Make gtk_binding_entry_add_signall() private
This function needs a replacement and that will appear after
refactorings.
2019-06-18 15:54:27 -04:00
Benjamin Otte
d8d5cc9788 bindings: Hide structs 2019-06-18 15:54:07 -04:00
Benjamin Otte
2687a2eb8d bindings: Remove unused member variables 2019-06-18 15:53:48 -04:00
Benjamin Otte
c0bbfd950d x11: Actually call the finished func when finishing
Copy/paste madness was calling the status func...
2019-06-18 15:53:18 -04:00
Benjamin Otte
d541aed165 testgtk: Remove unused code
This code has been doing nothing since 2010 when the optionmenu was
removed in 274395063a.
2019-06-18 15:53:01 -04:00
Benjamin Otte
c2ac141031 contentformats: Fix doc typo 2019-06-18 15:50:53 -04:00
Matthias Clasen
cdee8270e2 Merge branch 'widget-class-actions-2' into 'master'
Widget class action

See merge request GNOME/gtk!948
2019-06-18 19:10:45 +00:00
Matthias Clasen
6581d66652 Docs: expand actions chapter
Mention widget class actions and non-global actions
in various places.
2019-06-18 14:50:24 -04:00
Matthias Clasen
7dbeee5d50 color chooser widget: Use the new action machinery
Port GtkColorChooserWidget to use widget class actions.

Note that this also changes the names of
the GtkColorChooserWidget actions away from a generic
"context" prefix.
2019-06-18 14:48:02 -04:00
Matthias Clasen
01e89f9142 link button: Use the new action machinery
Port GtkLinkButton to use widget class actions.

Note that this also changes the names of
the GtkLinkButton actions away from a generic
"context" prefix.
2019-06-18 14:47:33 -04:00
Matthias Clasen
dafb7054a1 window: Use the new action machinery
Change the default.activate action to use the
new action machinery.
2019-06-18 14:47:33 -04:00
Matthias Clasen
04bace1982 textview: Use the new action machinery
Port GtkTextView to use widget class actions.

Note that this also changes the names of
the GtkTextView actions away from a generic
"context" prefix.
2019-06-18 14:47:33 -04:00
Matthias Clasen
90701cb655 label: Use the new action machinery
Port GtkLabel to use widget class actions.

Note that this also changes the names of
the GtkLabel actions away from a generic
"context" prefix.
2019-06-18 14:47:33 -04:00
Matthias Clasen
ccccaa2681 password entry: Adapt to action name change
Also fix updating the icon when changing visibility
via the context menu.
2019-06-18 14:47:33 -04:00
Matthias Clasen
421e9c3502 text: Use the new action machinery
Port GtkText to use widget class actions.

Note that this also changes the names of
the GtkText actions away from a generic
"context" prefix.
2019-06-18 14:47:33 -04:00
Matthias Clasen
ef031e1a9d Allow registering actions per-class
Add a facility to register and install actions
at class init time. The intended use for these
actions is for

a) context and other model-based menus
b) key bindings

Most of these actions are going to be stateless,
so add separate apis for the simple and stateful
cases.

We avoid creating an action group for these by
teaching the action muxer about these actions.
The action muxer also maintains the enabled
state for these actions.
2019-06-18 14:47:33 -04:00
Matthias Clasen
9b62da10e6 Give the action muxer a widget
This will be used in the future to obtain
widget class actions.
2019-06-18 06:12:50 -04:00
Jakub Steiner
aa6f5dae5a Adwaita: tone down infobars
Fixes https://gitlab.gnome.org/GNOME/gtk/issues/1957
2019-06-18 10:25:54 +02:00
Matthias Clasen
0b1efebb39 Merge branch 'egl-config-8888' into 'master'
wayland: Explicitly require RGBA8888

See merge request GNOME/gtk!944
2019-06-17 17:03:21 +00:00
Matthias Clasen
bbea1cc841 wayland: Explicitly require RGBA8888
Its the format we expect to have. If we want to
support 10-bit visuals at some point, that should
be an explicit decision.
2019-06-17 12:41:01 -04:00
Matthias Clasen
97ba872ef3 Merge branch 'matthiasc-for-master' into 'master'
Matthiasc for master

See merge request GNOME/gtk!943
2019-06-17 03:26:35 +00:00
Matthias Clasen
a5c327bb02 popover: Drop unused api
The inspector is no longer using this
list model, so drop the api.
2019-06-16 23:03:34 -04:00
Matthias Clasen
bda5a8214b inspector: Don't duplicate popovers
Popovers are now regular children in the widget
tree, no need to duplicate them as toplevels
in the object tree.
2019-06-16 23:03:27 -04:00
Matthias Clasen
3ad8797068 inspector: Add a refresh button for actions
Action state updates may not always be precise.
2019-06-16 23:03:19 -04:00
Matthias Clasen
2457ed03c2 inspector: Fix centering of subtitles 2019-06-16 23:03:12 -04:00
Piotr Drąg
4623642925 Update Polish translation 2019-06-16 13:34:36 +02:00
Matthias Clasen
75713a9e47 Merge branch 'matthiasc-for-master' into 'master'
Matthiasc for master

See merge request GNOME/gtk!942
2019-06-16 01:59:58 +00:00
Matthias Clasen
cc667926d6 Drop gtk_widget_get_action_group
Ths api exposes too much of the internal
action muxer setup; we want to add actions
to the muxer without an action group.
2019-06-15 21:41:11 -04:00
Matthias Clasen
bc56860fa1 places sidebar: Stop using gtk_widget_get_action_group
We create this action group ourselves,
we can keep track of it.
2019-06-15 21:41:03 -04:00
Matthias Clasen
820929958d file chooser: Stop using gtk_widget_get_action_group
We create this action group ourselves,
we can keep track of it.
2019-06-15 21:40:55 -04:00
Matthias Clasen
72d306c132 entry: Remove hacky code
We can leave it up to apps to not set less-than-useful
combinations, such as show-emoji-icon, but a no-emoji
input hint.
2019-06-15 21:40:50 -04:00
Matthias Clasen
9bb2d1eb5c widget: Remove gtk_widget_list_action_prefixes
This function was added just for the inspector,
and is not used there anymore. Drop it.
2019-06-15 21:40:38 -04:00
Matthias Clasen
d2e0d3222f widget: Cosmetics 2019-06-15 21:40:33 -04:00
Matthias Clasen
44970b5182 inspector: Fix actionable handling 2019-06-15 21:40:28 -04:00
Matthias Clasen
00c828e752 inspector: Redo the action page
Instead of iterating action groups manually,
just show what the action muxer provides. This
gives an accurate view of what actions are
available in a widgets context, and saves us
the trouble of juggling prefixes manually.
2019-06-15 21:40:22 -04:00
Matthias Clasen
3b565d7f6e action muxer: cosmetics 2019-06-15 21:40:17 -04:00
Matthias Clasen
db7f0189dd action muxer: Add some convenience api
Instead of duplicating this code in multiple places,
add an api to look up an action group for a prefixed
name, and return the unprefixed name at the same time.
2019-06-15 21:40:12 -04:00
Matthias Clasen
d2a794b411 menu tracker item: Improve logging
Pass the action name along, so we can put
it in log messages.
2019-06-15 21:40:06 -04:00
Matthias Clasen
8cfdd6c591 Remove an accidental addition 2019-06-15 00:51:46 -04:00
Daniel Boles
732630e0e2 testsuite/a11y/about: Fix exp. output per 31066a69
cherry-pick of commit e56a9e6ce5

Close #1949
2019-06-14 18:05:06 +01:00
Alex Monday
afbadc5e1b Adwaita: Fix fine-tune mode for scales with marks
Remove old fine-tune marks style, add margins for fine-tune marks to
compensate trough growth, prevent horizontal fine-tune trough growth in
horizontal direction, prevent vertical fine-tune trough growth in
vertical direction.

Closes https://gitlab.gnome.org/GNOME/gtk/issues/1799
2019-04-01 14:48:45 +05:00
617 changed files with 206258 additions and 72524 deletions

View File

@@ -1,7 +1,7 @@
stages:
- build
- flatpak
- deploy
# - deploy
.cache-paths: &cache-paths
paths:
@@ -101,20 +101,19 @@ flatpak-master:icon-browser:
APPID: org.gtk.IconBrowser4
<<: *flatpak-master
pages:
image: registry.gitlab.gnome.org/gnome/gtk/master:v6
stage: deploy
script:
- meson -Ddocumentation=true _build .
- ninja -C _build
- ninja -C _build gdk4-doc gsk4-doc gtk4-doc
- mkdir -p public/
- mv _build/docs/reference/gtk/html/ public/gtk/
- mv _build/docs/reference/gdk/html/ public/gdk/
- mv _build/docs/reference/gsk/html/ public/gsk/
artifacts:
paths:
- public
only:
- master
#pages:
# image: registry.gitlab.gnome.org/gnome/gtk/master:v6
# stage: deploy
# script:
# - meson -Dgtk_doc=true _build .
# - ninja -C _build
# - ninja -C _build gdk4-doc gsk4-doc gtk4-doc
# - mkdir -p public/
# - mv _build/docs/reference/gtk/html/ public/gtk/
# - mv _build/docs/reference/gdk/html/ public/gdk/
# - mv _build/docs/reference/gsk/html/ public/gsk/
# artifacts:
# paths:
# - public
# only:
# - master

View File

@@ -56,12 +56,6 @@
/* Define if GStreamer support is available */
#mesondefine HAVE_GSTREAMER
/* Define to 1 if you have the `httpGetAuthString' function. */
#mesondefine HAVE_HTTPGETAUTHSTRING
/* Define if cups http_t authstring field is accessible */
#mesondefine HAVE_HTTP_AUTHSTRING
/* Define to 1 if you have the <inttypes.h> header file. */
#mesondefine HAVE_INTTYPES_H
@@ -191,9 +185,6 @@
/* Define to the sub-directory where libtool stores uninstalled libraries. */
#mesondefine LT_OBJDIR
/* Define if <X11/extensions/XIproto.h> needed for xReply */
#mesondefine NEED_XIPROTO_H_FOR_XREPLY
/* Define to 1 if your C compiler doesn't accept -c and -o together. */
#mesondefine NO_MINUS_C_MINUS_O

View File

@@ -0,0 +1,115 @@
/*
* Copyright © 2019 Red Hat, Inc.
*
* 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: Matthias Clasen
*/
#include "config.h"
#include "constraint-editor-application.h"
#include "constraint-editor-window.h"
struct _ConstraintEditorApplication
{
GtkApplication parent_instance;
};
G_DEFINE_TYPE(ConstraintEditorApplication, constraint_editor_application, GTK_TYPE_APPLICATION);
static void
constraint_editor_application_init (ConstraintEditorApplication *app)
{
}
static void
quit_activated (GSimpleAction *action,
GVariant *parameter,
gpointer data)
{
g_application_quit (G_APPLICATION (data));
}
static GActionEntry app_entries[] =
{
{ "quit", quit_activated, NULL, NULL, NULL }
};
static void
constraint_editor_application_startup (GApplication *app)
{
const char *quit_accels[2] = { "<Ctrl>Q", NULL };
const char *open_accels[2] = { "<Ctrl>O", NULL };
GtkCssProvider *provider;
G_APPLICATION_CLASS (constraint_editor_application_parent_class)->startup (app);
g_action_map_add_action_entries (G_ACTION_MAP (app),
app_entries, G_N_ELEMENTS (app_entries),
app);
gtk_application_set_accels_for_action (GTK_APPLICATION (app), "app.quit", quit_accels);
gtk_application_set_accels_for_action (GTK_APPLICATION (app), "win.open", open_accels);
provider = gtk_css_provider_new ();
gtk_css_provider_load_from_resource (provider, "/org/gtk/gtk4/constraint-editor/constraint-editor.css");
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
GTK_STYLE_PROVIDER (provider),
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
}
static void
constraint_editor_application_activate (GApplication *app)
{
ConstraintEditorWindow *win;
win = constraint_editor_window_new (CONSTRAINT_EDITOR_APPLICATION (app));
gtk_window_present (GTK_WINDOW (win));
}
static void
constraint_editor_application_open (GApplication *app,
GFile **files,
gint n_files,
const gchar *hint)
{
ConstraintEditorWindow *win;
gint i;
for (i = 0; i < n_files; i++)
{
win = constraint_editor_window_new (CONSTRAINT_EDITOR_APPLICATION (app));
constraint_editor_window_load (win, files[i]);
gtk_window_present (GTK_WINDOW (win));
}
}
static void
constraint_editor_application_class_init (ConstraintEditorApplicationClass *class)
{
GApplicationClass *application_class = G_APPLICATION_CLASS (class);
application_class->startup = constraint_editor_application_startup;
application_class->activate = constraint_editor_application_activate;
application_class->open = constraint_editor_application_open;
}
ConstraintEditorApplication *
constraint_editor_application_new (void)
{
return g_object_new (CONSTRAINT_EDITOR_APPLICATION_TYPE,
"application-id", "org.gtk.gtk4.ConstraintEditor",
"flags", G_APPLICATION_HANDLES_OPEN,
NULL);
}

View File

@@ -0,0 +1,28 @@
/*
* Copyright © 2019 Red Hat, Inc.
*
* 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: Matthias Clasen
*/
#pragma once
#include <gtk/gtk.h>
#define CONSTRAINT_EDITOR_APPLICATION_TYPE (constraint_editor_application_get_type ())
G_DECLARE_FINAL_TYPE (ConstraintEditorApplication, constraint_editor_application, CONSTRAINT, EDITOR_APPLICATION, GtkApplication)
ConstraintEditorApplication *constraint_editor_application_new (void);

View File

@@ -0,0 +1,639 @@
/*
* Copyright © 2019 Red Hat, Inc.
*
* 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: Matthias Clasen
*/
#include "config.h"
#include "constraint-editor-window.h"
#include "constraint-view.h"
#include "constraint-editor.h"
#include "guide-editor.h"
struct _ConstraintEditorWindow
{
GtkApplicationWindow parent_instance;
GtkWidget *paned;
GtkWidget *view;
GtkWidget *list;
};
G_DEFINE_TYPE(ConstraintEditorWindow, constraint_editor_window, GTK_TYPE_APPLICATION_WINDOW);
static GtkConstraintTarget *
find_target (GListModel *model,
GtkConstraintTarget *orig)
{
const char *name;
const char *model_name;
gpointer item;
int i;
if (orig == NULL)
return NULL;
if (GTK_IS_LABEL (orig))
name = gtk_label_get_label (GTK_LABEL (orig));
else if (GTK_IS_CONSTRAINT_GUIDE (orig))
name = gtk_constraint_guide_get_name (GTK_CONSTRAINT_GUIDE (orig));
else
{
g_warning ("Don't know how to handle %s targets", G_OBJECT_TYPE_NAME (orig));
return NULL;
}
for (i = 0; i < g_list_model_get_n_items (model); i++)
{
item = g_list_model_get_item (model, i);
g_object_unref (item);
if (GTK_IS_WIDGET (item))
model_name = gtk_widget_get_name (GTK_WIDGET (item));
else
model_name = gtk_constraint_guide_get_name (GTK_CONSTRAINT_GUIDE (item));
if (strcmp (name, model_name) == 0)
return GTK_CONSTRAINT_TARGET (item);
}
g_warning ("Failed to find target '%s'", name);
return NULL;
}
gboolean
constraint_editor_window_load (ConstraintEditorWindow *self,
GFile *file)
{
char *path;
GtkBuilder *builder;
GError *error = NULL;
GtkWidget *view;
GtkLayoutManager *layout;
GtkWidget *child;
const char *name;
gpointer item;
int i;
GListModel *list;
path = g_file_get_path (file);
builder = gtk_builder_new ();
if (!gtk_builder_add_from_file (builder, path, &error))
{
g_print ("Could not load %s: %s", path, error->message);
g_error_free (error);
g_free (path);
g_object_unref (builder);
return FALSE;
}
view = GTK_WIDGET (gtk_builder_get_object (builder, "view"));
if (!GTK_IS_BOX (view))
{
g_print ("Could not load %s: No GtkBox named 'view'", path);
g_free (path);
g_object_unref (builder);
return FALSE;
}
layout = gtk_widget_get_layout_manager (view);
if (!GTK_IS_CONSTRAINT_LAYOUT (layout))
{
g_print ("Could not load %s: Widget 'view' does not use GtkConstraintLayout", path);
g_free (path);
g_object_unref (builder);
return FALSE;
}
for (child = gtk_widget_get_first_child (view);
child;
child = gtk_widget_get_next_sibling (child))
{
if (!GTK_IS_LABEL (child))
{
g_print ("Skipping non-GtkLabel child\n");
continue;
}
name = gtk_label_get_label (GTK_LABEL (child));
constraint_view_add_child (CONSTRAINT_VIEW (self->view), name);
}
list = gtk_constraint_layout_observe_guides (GTK_CONSTRAINT_LAYOUT (layout));
for (i = 0; i < g_list_model_get_n_items (list); i++)
{
GtkConstraintGuide *guide, *clone;
int w, h;
item = g_list_model_get_item (list, i);
guide = GTK_CONSTRAINT_GUIDE (item);
/* need to clone here, to attach to the right targets */
clone = gtk_constraint_guide_new ();
gtk_constraint_guide_set_name (clone, gtk_constraint_guide_get_name (guide));
gtk_constraint_guide_set_strength (clone, gtk_constraint_guide_get_strength (guide));
gtk_constraint_guide_get_min_size (guide, &w, &h);
gtk_constraint_guide_set_min_size (clone, w, h);
gtk_constraint_guide_get_nat_size (guide, &w, &h);
gtk_constraint_guide_set_nat_size (clone, w, h);
gtk_constraint_guide_get_max_size (guide, &w, &h);
gtk_constraint_guide_set_max_size (clone, w, h);
constraint_view_add_guide (CONSTRAINT_VIEW (self->view), clone);
g_object_unref (guide);
g_object_unref (clone);
}
g_object_unref (list);
list = gtk_constraint_layout_observe_constraints (GTK_CONSTRAINT_LAYOUT (layout));
for (i = 0; i < g_list_model_get_n_items (list); i++)
{
GtkConstraint *constraint;
GtkConstraint *clone;
GtkConstraintTarget *target;
GtkConstraintTarget *source;
item = g_list_model_get_item (list, i);
constraint = GTK_CONSTRAINT (item);
target = gtk_constraint_get_target (constraint);
source = gtk_constraint_get_source (constraint);
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));
constraint_view_add_constraint (CONSTRAINT_VIEW (self->view), clone);
g_object_unref (constraint);
g_object_unref (clone);
}
g_object_unref (list);
g_free (path);
g_object_unref (builder);
return TRUE;
}
static void
open_response_cb (GtkNativeDialog *dialog,
gint response,
ConstraintEditorWindow *self)
{
gtk_native_dialog_hide (dialog);
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)
{
GtkFileChooserNative *dialog;
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);
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), ".");
g_signal_connect (dialog, "response", G_CALLBACK (open_response_cb), self);
gtk_native_dialog_show (GTK_NATIVE_DIALOG (dialog));
}
static void
serialize_child (GString *str,
int indent,
GtkWidget *child)
{
const char *name;
name = gtk_widget_get_name (child);
g_string_append_printf (str, "%*s<child>\n", indent, "");
g_string_append_printf (str, "%*s <object class=\"GtkLabel\" id=\"%s\">\n", indent, "", name);
g_string_append_printf (str, "%*s <property name=\"label\">%s</property>\n", indent, "", name);
g_string_append_printf (str, "%*s </object>\n", indent, "");
g_string_append_printf (str, "%*s</child>\n", indent, "");
}
static char *
serialize_model (GListModel *list)
{
GString *str = g_string_new ("");
int i;
g_string_append (str, "<interface>\n");
g_string_append (str, " <object class=\"GtkBox\" id=\"view\">\n");
g_string_append (str, " <property name=\"layout-manager\">\n");
g_string_append (str, " <object class=\"GtkConstraintLayout\">\n");
g_string_append (str, " <constraints>\n");
for (i = 0; i < g_list_model_get_n_items (list); i++)
{
gpointer item = g_list_model_get_item (list, i);
g_object_unref (item);
if (GTK_IS_CONSTRAINT (item))
constraint_editor_serialize_constraint (str, 10, GTK_CONSTRAINT (item));
else if (GTK_IS_CONSTRAINT_GUIDE (item))
guide_editor_serialize_guide (str, 10, GTK_CONSTRAINT_GUIDE (item));
}
g_string_append (str, " </constraints>\n");
g_string_append (str, " </object>\n");
g_string_append (str, " </property>\n");
for (i = 0; i < g_list_model_get_n_items (list); i++)
{
gpointer item = g_list_model_get_item (list, i);
g_object_unref (item);
if (GTK_IS_WIDGET (item))
serialize_child (str, 4, GTK_WIDGET (item));
}
g_string_append (str, " </object>\n");
g_string_append (str, "</interface>\n");
return g_string_free (str, FALSE);
}
static void
save_response_cb (GtkNativeDialog *dialog,
gint response,
ConstraintEditorWindow *self)
{
gtk_native_dialog_hide (dialog);
if (response == GTK_RESPONSE_ACCEPT)
{
GListModel *model;
char *text, *filename;
GError *error = NULL;
model = constraint_view_get_model (CONSTRAINT_VIEW (self->view));
text = serialize_model (model);
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
if (!g_file_set_contents (filename, text, -1, &error))
{
GtkWidget *dialog;
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 (dialog),
"%s", error->message);
g_signal_connect (dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL);
gtk_widget_show (dialog);
g_error_free (error);
}
g_free (filename);
}
gtk_native_dialog_destroy (dialog);
}
static void
save_cb (GtkWidget *button,
ConstraintEditorWindow *self)
{
GtkFileChooserNative *dialog;
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);
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (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_finalize (GObject *object)
{
//ConstraintEditorWindow *self = (ConstraintEditorWindow *)object;
G_OBJECT_CLASS (constraint_editor_window_parent_class)->finalize (object);
}
static int child_counter;
static int guide_counter;
static void
add_child (ConstraintEditorWindow *win)
{
char *name;
child_counter++;
name = g_strdup_printf ("Child %d", child_counter);
constraint_view_add_child (CONSTRAINT_VIEW (win->view), name);
g_free (name);
}
static void
add_guide (ConstraintEditorWindow *win)
{
char *name;
GtkConstraintGuide *guide;
guide_counter++;
name = g_strdup_printf ("Guide %d", guide_counter);
guide = gtk_constraint_guide_new ();
gtk_constraint_guide_set_name (guide, name);
g_free (name);
constraint_view_add_guide (CONSTRAINT_VIEW (win->view), guide);
}
static void
constraint_editor_done (ConstraintEditor *editor,
GtkConstraint *constraint,
ConstraintEditorWindow *win)
{
GtkConstraint *old_constraint;
g_object_get (editor, "constraint", &old_constraint, NULL);
if (old_constraint)
constraint_view_remove_constraint (CONSTRAINT_VIEW (win->view), old_constraint);
constraint_view_add_constraint (CONSTRAINT_VIEW (win->view), constraint);
g_clear_object (&old_constraint);
gtk_widget_destroy (gtk_widget_get_ancestor (GTK_WIDGET (editor), GTK_TYPE_WINDOW));
}
static void
edit_constraint (ConstraintEditorWindow *win,
GtkConstraint *constraint)
{
GtkWidget *window;
ConstraintEditor *editor;
GListModel *model;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (win));
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
if (constraint)
gtk_window_set_title (GTK_WINDOW (window), "Edit Constraint");
else
gtk_window_set_title (GTK_WINDOW (window), "Create Constraint");
model = constraint_view_get_model (CONSTRAINT_VIEW (win->view));
editor = constraint_editor_new (model, constraint);
gtk_container_add (GTK_CONTAINER (window), GTK_WIDGET (editor));
g_signal_connect (editor, "done", G_CALLBACK (constraint_editor_done), win);
gtk_widget_show (window);
}
static void
add_constraint (ConstraintEditorWindow *win)
{
edit_constraint (win, NULL);
}
static void
guide_editor_done (GuideEditor *editor,
GtkConstraintGuide *guide,
ConstraintEditorWindow *win)
{
gtk_widget_destroy (gtk_widget_get_ancestor (GTK_WIDGET (editor), GTK_TYPE_WINDOW));
}
static void
edit_guide (ConstraintEditorWindow *win,
GtkConstraintGuide *guide)
{
GtkWidget *window;
GuideEditor *editor;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (win));
gtk_window_set_title (GTK_WINDOW (window), "Edit Guide");
editor = guide_editor_new (guide);
gtk_container_add (GTK_CONTAINER (window), GTK_WIDGET (editor));
g_signal_connect (editor, "done", G_CALLBACK (guide_editor_done), win);
gtk_widget_show (window);
}
static void
row_activated (GtkListBox *list,
GtkListBoxRow *row,
ConstraintEditorWindow *win)
{
GObject *item;
item = G_OBJECT (g_object_get_data (G_OBJECT (row), "item"));
if (GTK_IS_CONSTRAINT (item))
edit_constraint (win, GTK_CONSTRAINT (item));
else if (GTK_IS_CONSTRAINT_GUIDE (item))
edit_guide (win, GTK_CONSTRAINT_GUIDE (item));
}
static void
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->finalize = constraint_editor_window_finalize;
gtk_widget_class_set_template_from_resource (widget_class,
"/org/gtk/gtk4/constraint-editor/constraint-editor-window.ui");
gtk_widget_class_bind_template_child (widget_class, ConstraintEditorWindow, paned);
gtk_widget_class_bind_template_child (widget_class, ConstraintEditorWindow, view);
gtk_widget_class_bind_template_child (widget_class, ConstraintEditorWindow, list);
gtk_widget_class_bind_template_callback (widget_class, open_cb);
gtk_widget_class_bind_template_callback (widget_class, save_cb);
gtk_widget_class_bind_template_callback (widget_class, add_child);
gtk_widget_class_bind_template_callback (widget_class, add_guide);
gtk_widget_class_bind_template_callback (widget_class, add_constraint);
gtk_widget_class_bind_template_callback (widget_class, row_activated);
}
static void
row_edit (GtkButton *button,
ConstraintEditorWindow *win)
{
GtkWidget *row;
GObject *item;
row = gtk_widget_get_ancestor (GTK_WIDGET (button), GTK_TYPE_LIST_BOX_ROW);
item = (GObject *)g_object_get_data (G_OBJECT (row), "item");
if (GTK_IS_CONSTRAINT (item))
edit_constraint (win, GTK_CONSTRAINT (item));
else if (GTK_IS_CONSTRAINT_GUIDE (item))
edit_guide (win, GTK_CONSTRAINT_GUIDE (item));
}
static void
mark_constraints_invalid (ConstraintEditorWindow *win,
gpointer removed)
{
GtkWidget *child;
GObject *item;
for (child = gtk_widget_get_first_child (win->list);
child;
child = gtk_widget_get_next_sibling (child))
{
item = (GObject *)g_object_get_data (G_OBJECT (child), "item");
if (GTK_IS_CONSTRAINT (item))
{
GtkConstraint *constraint = GTK_CONSTRAINT (item);
if (gtk_constraint_get_target (constraint) == (GtkConstraintTarget *)removed ||
gtk_constraint_get_source (constraint) == (GtkConstraintTarget *)removed)
{
GtkWidget *button;
button = (GtkWidget *)g_object_get_data (G_OBJECT (child), "edit");
gtk_button_set_icon_name (GTK_BUTTON (button), "dialog-warning-symbolic");
gtk_widget_set_tooltip_text (button, "Constraint is invalid");
}
}
}
}
static void
row_delete (GtkButton *button,
ConstraintEditorWindow *win)
{
GtkWidget *row;
GObject *item;
row = gtk_widget_get_ancestor (GTK_WIDGET (button), GTK_TYPE_LIST_BOX_ROW);
item = (GObject *)g_object_get_data (G_OBJECT (row), "item");
if (GTK_IS_CONSTRAINT (item))
constraint_view_remove_constraint (CONSTRAINT_VIEW (win->view),
GTK_CONSTRAINT (item));
else if (GTK_IS_CONSTRAINT_GUIDE (item))
{
mark_constraints_invalid (win, item);
constraint_view_remove_guide (CONSTRAINT_VIEW (win->view),
GTK_CONSTRAINT_GUIDE (item));
}
else if (GTK_IS_WIDGET (item))
{
mark_constraints_invalid (win, item);
constraint_view_remove_child (CONSTRAINT_VIEW (win->view),
GTK_WIDGET (item));
}
}
static GtkWidget *
create_widget_func (gpointer item,
gpointer user_data)
{
ConstraintEditorWindow *win = user_data;
const char *name;
char *freeme = NULL;
GtkWidget *row, *box, *label, *button;
if (GTK_IS_WIDGET (item))
name = gtk_widget_get_name (GTK_WIDGET (item));
else if (GTK_IS_CONSTRAINT_GUIDE (item))
name = gtk_constraint_guide_get_name (GTK_CONSTRAINT_GUIDE (item));
else if (GTK_IS_CONSTRAINT (item))
name = freeme = constraint_editor_constraint_to_string (GTK_CONSTRAINT (item));
else
name = "";
row = gtk_list_box_row_new ();
g_object_set_data_full (G_OBJECT (row), "item", g_object_ref (item), g_object_unref);
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
label = gtk_label_new (name);
if (GTK_IS_WIDGET (item) || GTK_IS_CONSTRAINT_GUIDE (item))
g_object_bind_property (item, "name",
label, "label",
G_BINDING_DEFAULT);
g_object_set (label, "margin", 10, NULL);
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
gtk_widget_set_hexpand (label, TRUE);
gtk_container_add (GTK_CONTAINER (row), box);
gtk_container_add (GTK_CONTAINER (box), label);
if (GTK_IS_CONSTRAINT (item) || GTK_IS_CONSTRAINT_GUIDE (item))
{
button = gtk_button_new_from_icon_name ("document-edit-symbolic");
gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
g_signal_connect (button, "clicked", G_CALLBACK (row_edit), win);
g_object_set_data (G_OBJECT (row), "edit", button);
gtk_container_add (GTK_CONTAINER (box), button);
button = gtk_button_new_from_icon_name ("edit-delete-symbolic");
gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
g_signal_connect (button, "clicked", G_CALLBACK (row_delete), win);
gtk_container_add (GTK_CONTAINER (box), button);
}
else if (GTK_IS_WIDGET (item))
{
button = gtk_button_new_from_icon_name ("edit-delete-symbolic");
gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
g_signal_connect (button, "clicked", G_CALLBACK (row_delete), win);
gtk_container_add (GTK_CONTAINER (box), button);
}
g_free (freeme);
return row;
}
static void
constraint_editor_window_init (ConstraintEditorWindow *self)
{
gtk_widget_init_template (GTK_WIDGET (self));
gtk_list_box_bind_model (GTK_LIST_BOX (self->list),
constraint_view_get_model (CONSTRAINT_VIEW (self->view)),
create_widget_func,
self,
NULL);
}
ConstraintEditorWindow *
constraint_editor_window_new (ConstraintEditorApplication *application)
{
return g_object_new (CONSTRAINT_EDITOR_WINDOW_TYPE,
"application", application,
NULL);
}

View File

@@ -0,0 +1,34 @@
/*
* Copyright © 2019 Red Hat, Inc
*
* 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: Matthias Clasen
*/
#pragma once
#include <gtk/gtk.h>
#include "constraint-editor-application.h"
#define CONSTRAINT_EDITOR_WINDOW_TYPE (constraint_editor_window_get_type ())
G_DECLARE_FINAL_TYPE (ConstraintEditorWindow, constraint_editor_window, CONSTRAINT, EDITOR_WINDOW, GtkApplicationWindow)
ConstraintEditorWindow * constraint_editor_window_new (ConstraintEditorApplication *application);
gboolean constraint_editor_window_load (ConstraintEditorWindow *self,
GFile *file);

View File

@@ -0,0 +1,82 @@
<?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="title" translatable="yes">GTK Constraint Editor</property>
<property name="show-title-buttons">1</property>
<child type="start">
<object class="GtkButton">
<property name="icon-name">document-open-symbolic</property>
<property name="tooltip-text">Open ui file</property>
<signal name="clicked" handler="open_cb"/>
</object>
</child>
<child type="start">
<object class="GtkButton">
<property name="icon-name">document-save-symbolic</property>
<property name="tooltip-text">Save to ui file</property>
<signal name="clicked" handler="save_cb"/>
</object>
</child>
</object>
</child>
<child>
<object class="GtkPaned" id="paned">
<property name="orientation">horizontal</property>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="GtkBox">
<property name="orientation">horizontal</property>
<child>
<object class="GtkButton">
<property name="label">Add Child</property>
<signal name="clicked" handler="add_child" swapped="yes"/>
</object>
</child>
<child>
<object class="GtkButton">
<property name="label">Add Guide</property>
<signal name="clicked" handler="add_guide" swapped="yes"/>
</object>
</child>
<child>
<object class="GtkButton">
<property name="label">Add Constraint</property>
<signal name="clicked" handler="add_constraint" swapped="yes"/>
</object>
</child>
</object>
</child>
<child>
<object class="GtkScrolledWindow">
<property name="hscrollbar-policy">never</property>
<property name="vscrollbar-policy">automatic</property>
<property name="vexpand">1</property>
<child>
<object class="GtkListBox" id="list">
<property name="show-separators">1</property>
<property name="selection-mode">none</property>
<signal name="row-activated" handler="row_activated"/>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="ConstraintView" id="view">
</object>
</child>
</object>
</child>
</template>
</interface>

View File

@@ -0,0 +1,656 @@
/*
* Copyright © 2019 Red Hat, Inc.
*
* 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: Matthias Clasen
*/
#include "config.h"
#include "constraint-editor.h"
struct _ConstraintEditor
{
GtkWidget parent_instance;
GtkWidget *grid;
GtkWidget *target;
GtkWidget *target_attr;
GtkWidget *relation;
GtkWidget *source;
GtkWidget *source_attr;
GtkWidget *multiplier;
GtkWidget *constant;
GtkWidget *strength;
GtkWidget *preview;
GtkWidget *button;
GtkConstraint *constraint;
GListModel *model;
gboolean constructed;
};
enum {
PROP_MODEL = 1,
PROP_CONSTRAINT,
LAST_PROP
};
static GParamSpec *pspecs[LAST_PROP];
enum {
DONE,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL];
G_DEFINE_TYPE(ConstraintEditor, constraint_editor, GTK_TYPE_WIDGET);
static const char *
get_target_name (GtkConstraintTarget *target)
{
if (target == NULL)
return "super";
else if (GTK_IS_WIDGET (target))
return gtk_widget_get_name (GTK_WIDGET (target));
else if (GTK_IS_CONSTRAINT_GUIDE (target))
return gtk_constraint_guide_get_name (GTK_CONSTRAINT_GUIDE (target));
else
return "";
}
static void
constraint_target_combo (GListModel *model,
GtkWidget *combo,
gboolean is_source)
{
int i;
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;
name = get_target_name (GTK_CONSTRAINT_TARGET (item));
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), name, name);
g_object_unref (item);
}
}
}
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
get_target (GListModel *model,
const char *id)
{
int i;
if (strcmp ("super", id) == 0)
return NULL;
for (i = 0; i < g_list_model_get_n_items (model); i++)
{
GObject *item = g_list_model_get_object (model, i);
g_object_unref (item);
if (GTK_IS_CONSTRAINT (item))
continue;
else if (GTK_IS_WIDGET (item))
{
if (strcmp (id, gtk_widget_get_name (GTK_WIDGET (item))) == 0)
return item;
}
else if (GTK_IS_CONSTRAINT_GUIDE (item))
{
if (strcmp (id, gtk_constraint_guide_get_name (GTK_CONSTRAINT_GUIDE (item))) == 0)
return item;
}
}
return NULL;
}
static GtkConstraintAttribute
get_target_attr (const char *id)
{
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);
return attr;
}
static const char *
get_attr_nick (GtkConstraintAttribute attr)
{
GEnumClass *class = g_type_class_ref (GTK_TYPE_CONSTRAINT_ATTRIBUTE);
GEnumValue *value = g_enum_get_value (class, attr);
const char *nick = value->value_nick;
g_type_class_unref (class);
return nick;
}
static GtkConstraintRelation
get_relation (const char *id)
{
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);
return relation;
}
static const char *
get_relation_nick (GtkConstraintRelation relation)
{
GEnumClass *class = g_type_class_ref (GTK_TYPE_CONSTRAINT_RELATION);
GEnumValue *value = g_enum_get_value (class, relation);
const char *nick = value->value_nick;
g_type_class_unref (class);
return nick;
}
static GtkConstraintStrength
get_strength (const char *id)
{
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 *
get_strength_nick (GtkConstraintStrength strength)
{
GEnumClass *class = g_type_class_ref (GTK_TYPE_CONSTRAINT_STRENGTH);
GEnumValue *value = g_enum_get_value (class, strength);
const char *nick = value->value_nick;
g_type_class_unref (class);
return nick;
}
void
constraint_editor_serialize_constraint (GString *str,
int indent,
GtkConstraint *constraint)
{
const char *target;
const char *target_attr;
const char *relation;
const char *source;
const char *source_attr;
double multiplier;
double constant;
const char *strength;
target = get_target_name (gtk_constraint_get_target (constraint));
target_attr = get_attr_nick (gtk_constraint_get_target_attribute (constraint));
relation = get_relation_nick (gtk_constraint_get_relation (constraint));
source = get_target_name (gtk_constraint_get_source (constraint));
source_attr = get_attr_nick (gtk_constraint_get_source_attribute (constraint));
multiplier = gtk_constraint_get_multiplier (constraint);
constant = gtk_constraint_get_constant (constraint);
strength = get_strength_nick (gtk_constraint_get_strength (constraint));
g_string_append_printf (str, "%*s<constraint target=\"%s\" target-attribute=\"%s\"\n", indent, "", target, target_attr);
g_string_append_printf (str, "%*s relation=\"%s\"\n", indent, "", relation);
if (strcmp (source_attr, "none") != 0)
{
g_string_append_printf (str, "%*s source=\"%s\" source-attribute=\"%s\"\n", indent, "", source, source_attr);
g_string_append_printf (str, "%*s multiplier=\"%g\"\n", indent, "", multiplier);
}
g_string_append_printf (str, "%*s constant=\"%g\"\n", indent, "", constant);
g_string_append_printf (str, "%*s strength=\"%s\" />\n", indent, "", strength);
}
static void
create_constraint (GtkButton *button,
ConstraintEditor *editor)
{
const char *id;
gpointer target;
GtkConstraintAttribute target_attr;
gpointer source;
GtkConstraintAttribute source_attr;
GtkConstraintRelation relation;
double multiplier;
double constant;
int strength;
GtkConstraint *constraint;
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);
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);
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);
id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->strength));
strength = get_strength (id);
constraint = gtk_constraint_new (target, target_attr,
relation,
source, source_attr,
multiplier,
constant,
strength);
g_signal_emit (editor, signals[DONE], 0, constraint);
g_object_unref (constraint);
}
static void
source_attr_changed (ConstraintEditor *editor)
{
const char *id;
id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->source_attr));
if (strcmp (id, "none") == 0)
{
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);
}
else
{
gtk_widget_set_sensitive (editor->source, TRUE);
gtk_widget_set_sensitive (editor->multiplier, TRUE);
}
}
char *
constraint_editor_constraint_to_string (GtkConstraint *constraint)
{
GString *str;
const char *name;
const char *attr;
const char *relation;
double c, m;
str = g_string_new ("");
name = get_target_name (gtk_constraint_get_target (constraint));
attr = get_attr_nick (gtk_constraint_get_target_attribute (constraint));
relation = get_relation_nick (gtk_constraint_get_relation (constraint));
if (name == NULL)
name = "[ ]";
g_string_append_printf (str, "%s.%s %s ", name, attr, relation);
c = gtk_constraint_get_constant (constraint);
attr = get_attr_nick (gtk_constraint_get_source_attribute (constraint));
if (strcmp (attr, "none") != 0)
{
name = get_target_name (gtk_constraint_get_source (constraint));
m = gtk_constraint_get_multiplier (constraint);
if (name == NULL)
name = "[ ]";
g_string_append_printf (str, "%s.%s", name, attr);
if (m != 1.0)
g_string_append_printf (str, " × %g", m);
if (c > 0.0)
g_string_append_printf (str, " + %g", c);
else if (c < 0.0)
g_string_append_printf (str, " - %g", -c);
}
else
g_string_append_printf (str, "%g", c);
return g_string_free (str, FALSE);
}
static void
update_preview (ConstraintEditor *editor)
{
GString *str;
const char *name;
const char *attr;
char *relation;
const char *multiplier;
const char *constant;
double c, m;
if (!editor->constructed)
return;
str = g_string_new ("");
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 = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->source_attr));
if (strcmp (attr, "none") != 0)
{
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);
if (name == NULL)
name = "[ ]";
g_string_append_printf (str, "%s.%s", name, attr);
if (m != 1.0)
g_string_append_printf (str, " × %g", m);
if (c > 0.0)
g_string_append_printf (str, " + %g", c);
else if (c < 0.0)
g_string_append_printf (str, " - %g", -c);
}
else
g_string_append_printf (str, "%g", c);
gtk_label_set_label (GTK_LABEL (editor->preview), str->str);
g_string_free (str, TRUE);
}
static void
update_button (ConstraintEditor *editor)
{
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);
}
static void
constraint_editor_init (ConstraintEditor *editor)
{
gtk_widget_init_template (GTK_WIDGET (editor));
}
static void
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)
{
GtkConstraintTarget *target;
GtkConstraintAttribute attr;
GtkConstraintRelation relation;
GtkConstraintStrength strength;
const char *nick;
char *val;
double multiplier;
double constant;
target = gtk_constraint_get_target (editor->constraint);
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);
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);
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);
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);
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);
gtk_editable_set_text (GTK_EDITABLE (editor->multiplier), val);
g_free (val);
constant = gtk_constraint_get_constant (editor->constraint);
val = g_strdup_printf ("%g", constant);
gtk_editable_set_text (GTK_EDITABLE (editor->constant), val);
g_free (val);
strength = gtk_constraint_get_strength (editor->constraint);
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_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");
gtk_button_set_label (GTK_BUTTON (editor->button), "Create");
}
editor->constructed = TRUE;
update_preview (editor);
update_button (editor);
}
static void
constraint_editor_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
ConstraintEditor *self = CONSTRAINT_EDITOR (object);
switch (property_id)
{
case PROP_MODEL:
self->model = g_value_dup_object (value);
break;
case PROP_CONSTRAINT:
self->constraint = g_value_dup_object (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
}
static void
constraint_editor_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
ConstraintEditor *self = CONSTRAINT_EDITOR (object);
switch (property_id)
{
case PROP_MODEL:
g_value_set_object (value, self->model);
break;
case PROP_CONSTRAINT:
g_value_set_object (value, self->constraint);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
}
static void
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);
G_OBJECT_CLASS (constraint_editor_parent_class)->dispose (object);
}
static void
constraint_editor_class_init (ConstraintEditorClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
object_class->constructed = constraint_editor_constructed;
object_class->dispose = constraint_editor_dispose;
object_class->set_property = constraint_editor_set_property;
object_class->get_property = constraint_editor_get_property;
pspecs[PROP_CONSTRAINT] =
g_param_spec_object ("constraint", "constraint", "constraint",
GTK_TYPE_CONSTRAINT,
G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY);
pspecs[PROP_MODEL] =
g_param_spec_object ("model", "model", "model",
G_TYPE_LIST_MODEL,
G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY);
g_object_class_install_properties (object_class, LAST_PROP, pspecs);
signals[DONE] =
g_signal_new ("done",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
NULL,
G_TYPE_NONE, 1, GTK_TYPE_CONSTRAINT);
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
gtk_widget_class_set_template_from_resource (widget_class,
"/org/gtk/gtk4/constraint-editor/constraint-editor.ui");
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, grid);
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, target);
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, target_attr);
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, relation);
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, source);
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, source_attr);
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, multiplier);
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, constant);
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, strength);
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, preview);
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, button);
gtk_widget_class_bind_template_callback (widget_class, update_preview);
gtk_widget_class_bind_template_callback (widget_class, update_button);
gtk_widget_class_bind_template_callback (widget_class, create_constraint);
gtk_widget_class_bind_template_callback (widget_class, source_attr_changed);
}
ConstraintEditor *
constraint_editor_new (GListModel *model,
GtkConstraint *constraint)
{
return g_object_new (CONSTRAINT_EDITOR_TYPE,
"model", model,
"constraint", constraint,
NULL);
}

View File

@@ -0,0 +1,12 @@
constraintview {
background: black;
color: white;
}
constraintview .child {
background: red;
}
constraintview .guide {
background: blue;
}

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/org/gtk/gtk4/constraint-editor">
<file preprocess="xml-stripblanks">constraint-editor-window.ui</file>
<file preprocess="xml-stripblanks">constraint-editor.ui</file>
<file preprocess="xml-stripblanks">guide-editor.ui</file>
<file>constraint-editor.css</file>
</gresource>
</gresources>

View File

@@ -0,0 +1,34 @@
/*
* Copyright © 2019 Red Hat, Inc
*
* 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: Matthias Clasen
*/
#pragma once
#include <gtk/gtk.h>
#define CONSTRAINT_EDITOR_TYPE (constraint_editor_get_type ())
G_DECLARE_FINAL_TYPE (ConstraintEditor, constraint_editor, CONSTRAINT, EDITOR, GtkWidget)
ConstraintEditor * constraint_editor_new (GListModel *model,
GtkConstraint *constraint);
void constraint_editor_serialize_constraint (GString *str,
int indent,
GtkConstraint *constraint);
char *constraint_editor_constraint_to_string (GtkConstraint *constraint);

View File

@@ -0,0 +1,163 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="ConstraintEditor" parent="GtkWidget">
<child>
<object class="GtkGrid" id="grid">
<property name="margin">20</property>
<property name="row-spacing">10</property>
<property name="column-spacing">10</property>
<child>
<object class="GtkLabel">
<property name="label">Target</property>
<layout>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkComboBoxText" id="target">
<signal name="changed" handler="update_preview" swapped="yes"/>
<signal name="changed" handler="update_button" swapped="yes"/>
<layout>
<property name="left-attach">1</property>
<property name="top-attach">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkComboBoxText" id="target_attr">
<signal name="changed" handler="update_preview" swapped="yes"/>
<layout>
<property name="left-attach">2</property>
<property name="top-attach">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Relation</property>
<layout>
<property name="left-attach">0</property>
<property name="top-attach">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkComboBoxText" id="relation">
<signal name="changed" handler="update_preview" swapped="yes"/>
<layout>
<property name="left-attach">1</property>
<property name="top-attach">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Source</property>
<layout>
<property name="left-attach">0</property>
<property name="top-attach">3</property>
</layout>
</object>
</child>
<child>
<object class="GtkComboBoxText" id="source">
<signal name="changed" handler="update_preview" swapped="yes"/>
<signal name="changed" handler="update_button" swapped="yes"/>
<layout>
<property name="left-attach">1</property>
<property name="top-attach">3</property>
</layout>
</object>
</child>
<child>
<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="left-attach">2</property>
<property name="top-attach">3</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Multiplier</property>
<layout>
<property name="left-attach">0</property>
<property name="top-attach">4</property>
</layout>
</object>
</child>
<child>
<object class="GtkEntry" id="multiplier">
<signal name="changed" handler="update_preview" swapped="yes"/>
<layout>
<property name="left-attach">1</property>
<property name="top-attach">4</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Constant</property>
<layout>
<property name="left-attach">0</property>
<property name="top-attach">5</property>
</layout>
</object>
</child>
<child>
<object class="GtkEntry" id="constant">
<signal name="changed" handler="update_preview" swapped="yes"/>
<layout>
<property name="left-attach">1</property>
<property name="top-attach">5</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Strength</property>
<layout>
<property name="left-attach">0</property>
<property name="top-attach">6</property>
</layout>
</object>
</child>
<child>
<object class="GtkComboBoxText" id="strength">
<layout>
<property name="left-attach">1</property>
<property name="top-attach">6</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel" id="preview">
<property name="xalign">0</property>
<layout>
<property name="left-attach">1</property>
<property name="top-attach">7</property>
<property name="column-span">2</property>
</layout>
<attributes>
<attribute name="scale" value="1.44"/>
</attributes>
</object>
</child>
<child>
<object class="GtkButton" id="button">
<property name="label">Create</property>
<signal name="clicked" handler="create_constraint"/>
<layout>
<property name="left-attach">2</property>
<property name="top-attach">8</property>
</layout>
</object>
</child>
</object>
</child>
</template>
</interface>

View File

@@ -0,0 +1,93 @@
/*
* Copyright © 2019 Red Hat, Inc
*
* 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: Matthias Clasen
*/
#include "constraint-view-child.h"
struct _ConstraintViewChild
{
GObject parent_instance;
char *name;
};
enum {
PROP_NAME = 1,
LAST_PROP
};
static GParamSpec props[LAST_PROP];
G_DEFINE_TYPE (ConstraintViewChild, constraint_view_child, G_TYPE_OBJECT)
static void
constraint_view_child_init (ConstraintViewChild *child)
{
}
static void
constraint_view_child_finalize (GObject *object)
{
ConstraintViewChild *child = CONSTRAINT_VIEW_CHILD (object);
g_free (child->name);
G_OBJECT_CLASS (constraint_view_child_parent_class)->finalize (object);
}
static void
constraint_view_child_set_property (GObject *object,
static void
constraint_view_child_class_init (ConstraintViewChildClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->finalize = constraint_view_child_finalize;
object_class->get_property = constraint_view_child_get_property;
object_class->set_property = constraint_view_child_set_property;
props[PROP_NAME] =
g_param_spec_string ("name", "name", "name",
NULL,
G_PARAM_READWRITE);
g_object_class_install_properties (object_class, LAST_PROP, props);
}
#define CONSTRAINT_VIEW_CHILD_TYPE (constraint_view_get_type ())
G_DECLARE_TYPE (ConstraintViewChild, constraint_view_child, CONSTRAINT, VIEW_CHILD, GObject)
#define CONSTRAINT_VIEW_WIDGET_TYPE (constraint_view_widget_get_type ())
G_DECLARE_FINAL_TYPE (ConstraintViewWidget, constraint_view_widget, CONSTRAINT, VIEW_WIDGET, ConstraintViewChild)
ConstraintViewWidget * constraint_view_widget_new (void);
#define CONSTRAINT_VIEW_GUIDE_TYPE (constraint_view_guide_get_type ())
G_DECLARE_FINAL_TYPE (ConstraintViewGuide, constraint_view_guide, CONSTRAINT, VIEW_GUIDE, ConstraintViewChild)
ConstraintViewGuide * constraint_view_guide_new (void);
#define CONSTRAINT_VIEW_CONSTRAINT_TYPE (constraint_view_constraint_get_type ())
G_DECLARE_FINAL_TYPE (ConstraintViewConstraint, constraint_view_constraint, CONSTRAINT, VIEW_CONSTRAINT, ConstraintViewChild)
ConstraintViewGuide * constraint_view_constraint_new (void);

View File

@@ -0,0 +1,44 @@
/*
* Copyright © 2019 Red Hat, Inc
*
* 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: Matthias Clasen
*/
#pragma once
#include <gtk/gtk.h>
#define CONSTRAINT_VIEW_CHILD_TYPE (constraint_view_get_type ())
G_DECLARE_TYPE (ConstraintViewChild, constraint_view_child, CONSTRAINT, VIEW_CHILD, GObject)
#define CONSTRAINT_VIEW_WIDGET_TYPE (constraint_view_widget_get_type ())
G_DECLARE_FINAL_TYPE (ConstraintViewWidget, constraint_view_widget, CONSTRAINT, VIEW_WIDGET, ConstraintViewChild)
ConstraintViewWidget * constraint_view_widget_new (void);
#define CONSTRAINT_VIEW_GUIDE_TYPE (constraint_view_guide_get_type ())
G_DECLARE_FINAL_TYPE (ConstraintViewGuide, constraint_view_guide, CONSTRAINT, VIEW_GUIDE, ConstraintViewChild)
ConstraintViewGuide * constraint_view_guide_new (void);
#define CONSTRAINT_VIEW_CONSTRAINT_TYPE (constraint_view_constraint_get_type ())
G_DECLARE_FINAL_TYPE (ConstraintViewConstraint, constraint_view_constraint, CONSTRAINT, VIEW_CONSTRAINT, ConstraintViewChild)
ConstraintViewGuide * constraint_view_constraint_new (void);

View File

@@ -0,0 +1,343 @@
/* Copyright (C) 2019 Red Hat, Inc.
*
* 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 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/>.
*/
#include <gtk/gtk.h>
#include "constraint-view.h"
struct _ConstraintView
{
GtkWidget parent;
GListModel *model;
GtkWidget *drag_widget;
};
G_DEFINE_TYPE (ConstraintView, constraint_view, GTK_TYPE_WIDGET);
static void
constraint_view_dispose (GObject *object)
{
ConstraintView *view = CONSTRAINT_VIEW (object);
GtkWidget *child;
while ((child = gtk_widget_get_first_child (GTK_WIDGET (view))) != NULL)
gtk_widget_unparent (child);
g_clear_object (&view->model);
G_OBJECT_CLASS (constraint_view_parent_class)->dispose (object);
}
static void
constraint_view_class_init (ConstraintViewClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
object_class->dispose = constraint_view_dispose;
gtk_widget_class_set_css_name (widget_class, "constraintview");
}
static void
update_weak_position (ConstraintView *self,
GtkWidget *child,
double x,
double y)
{
GtkLayoutManager *manager;
GtkConstraint *constraint;
manager = gtk_widget_get_layout_manager (GTK_WIDGET (self));
constraint = (GtkConstraint *)g_object_get_data (G_OBJECT (child), "x-constraint");
if (constraint)
{
gtk_constraint_layout_remove_constraint (GTK_CONSTRAINT_LAYOUT (manager),
constraint);
g_object_set_data (G_OBJECT (child), "x-constraint", NULL);
}
if (x != -100)
{
constraint = gtk_constraint_new_constant (child,
GTK_CONSTRAINT_ATTRIBUTE_CENTER_X,
GTK_CONSTRAINT_RELATION_EQ,
x,
GTK_CONSTRAINT_STRENGTH_WEAK);
g_object_set_data (G_OBJECT (constraint), "internal", "yes");
gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (manager),
constraint);
g_object_set_data (G_OBJECT (child), "x-constraint", constraint);
}
constraint = (GtkConstraint *)g_object_get_data (G_OBJECT (child), "y-constraint");
if (constraint)
{
gtk_constraint_layout_remove_constraint (GTK_CONSTRAINT_LAYOUT (manager),
constraint);
g_object_set_data (G_OBJECT (child), "y-constraint", NULL);
}
if (y != -100)
{
constraint = gtk_constraint_new_constant (child,
GTK_CONSTRAINT_ATTRIBUTE_CENTER_Y,
GTK_CONSTRAINT_RELATION_EQ,
y,
GTK_CONSTRAINT_STRENGTH_WEAK);
g_object_set_data (G_OBJECT (constraint), "internal", "yes");
gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (manager),
constraint);
g_object_set_data (G_OBJECT (child), "y-constraint", constraint);
}
}
static void
drag_begin (GtkGestureDrag *drag,
double start_x,
double start_y,
ConstraintView *self)
{
GtkWidget *widget;
widget = gtk_widget_pick (GTK_WIDGET (self), start_x, start_y, GTK_PICK_DEFAULT);
if (GTK_IS_LABEL (widget))
{
widget = gtk_widget_get_ancestor (widget, GTK_TYPE_FRAME);
if (widget &&
gtk_widget_get_parent (widget) == (GtkWidget *)self)
{
self->drag_widget = widget;
}
}
}
static void
drag_update (GtkGestureDrag *drag,
double offset_x,
double offset_y,
ConstraintView *self)
{
double x, y;
if (!self->drag_widget)
return;
gtk_gesture_drag_get_start_point (drag, &x, &y);
update_weak_position (self, self->drag_widget, x + offset_x, y + offset_y);
}
static void
drag_end (GtkGestureDrag *drag,
double offset_x,
double offset_y,
ConstraintView *self)
{
self->drag_widget = NULL;
}
static gboolean
omit_internal (gpointer item, gpointer user_data)
{
if (g_object_get_data (G_OBJECT (item), "internal"))
return FALSE;
return TRUE;
}
static void
constraint_view_init (ConstraintView *self)
{
GtkLayoutManager *manager;
GtkEventController *controller;
GListStore *list;
GListModel *all_children;
GListModel *all_constraints;
GListModel *guides;
GListModel *children;
GListModel *constraints;
manager = gtk_constraint_layout_new ();
gtk_widget_set_layout_manager (GTK_WIDGET (self), manager);
all_children = gtk_widget_observe_children (GTK_WIDGET (self));
all_constraints = gtk_constraint_layout_observe_constraints (GTK_CONSTRAINT_LAYOUT (manager));
guides = gtk_constraint_layout_observe_guides (GTK_CONSTRAINT_LAYOUT (manager));
constraints = (GListModel *)gtk_filter_list_model_new (all_constraints, omit_internal, NULL, NULL);
children = (GListModel *)gtk_filter_list_model_new (all_children, omit_internal, NULL, NULL);
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);
controller = (GtkEventController *)gtk_gesture_drag_new ();
g_signal_connect (controller, "drag-begin", G_CALLBACK (drag_begin), self);
g_signal_connect (controller, "drag-update", G_CALLBACK (drag_update), self);
g_signal_connect (controller, "drag-end", G_CALLBACK (drag_end), self);
gtk_widget_add_controller (GTK_WIDGET (self), controller);
}
ConstraintView *
constraint_view_new (void)
{
return g_object_new (CONSTRAINT_VIEW_TYPE, NULL);
}
void
constraint_view_add_child (ConstraintView *view,
const char *name)
{
GtkWidget *frame;
GtkWidget *label;
label = gtk_label_new (name);
frame = gtk_frame_new (NULL);
gtk_style_context_add_class (gtk_widget_get_style_context (frame), "child");
gtk_widget_set_name (frame, name);
gtk_container_add (GTK_CONTAINER (frame), label);
gtk_widget_set_parent (frame, GTK_WIDGET (view));
update_weak_position (view, frame, 100, 100);
}
void
constraint_view_remove_child (ConstraintView *view,
GtkWidget *child)
{
update_weak_position (view, child, -100, -100);
gtk_widget_unparent (child);
}
void
constraint_view_add_guide (ConstraintView *view,
GtkConstraintGuide *guide)
{
GtkConstraintLayout *layout;
GtkWidget *frame;
GtkWidget *label;
const char *name;
GtkConstraint *constraint;
struct {
const char *name;
GtkConstraintAttribute attr;
} names[] = {
{ "left-constraint", GTK_CONSTRAINT_ATTRIBUTE_LEFT },
{ "top-constraint", GTK_CONSTRAINT_ATTRIBUTE_TOP },
{ "width-constraint", GTK_CONSTRAINT_ATTRIBUTE_WIDTH },
{ "height-constraint", GTK_CONSTRAINT_ATTRIBUTE_HEIGHT },
};
int i;
name = gtk_constraint_guide_get_name (guide);
label = gtk_label_new (name);
g_object_bind_property (guide, "name",
label, "label",
G_BINDING_DEFAULT);
frame = gtk_frame_new (NULL);
gtk_style_context_add_class (gtk_widget_get_style_context (frame), "guide");
g_object_set_data (G_OBJECT (frame), "internal", "yes");
gtk_container_add (GTK_CONTAINER (frame), label);
gtk_widget_insert_after (frame, GTK_WIDGET (view), NULL);
g_object_set_data (G_OBJECT (guide), "frame", frame);
layout = GTK_CONSTRAINT_LAYOUT (gtk_widget_get_layout_manager (GTK_WIDGET (view)));
gtk_constraint_layout_add_guide (layout, g_object_ref (guide));
for (i = 0; i < G_N_ELEMENTS (names); i++)
{
constraint = gtk_constraint_new (frame,
names[i].attr,
GTK_CONSTRAINT_RELATION_EQ,
guide,
names[i].attr,
1.0, 0.0,
GTK_CONSTRAINT_STRENGTH_REQUIRED);
g_object_set_data (G_OBJECT (constraint), "internal", "yes");
gtk_constraint_layout_add_constraint (layout, constraint);
g_object_set_data (G_OBJECT (guide), names[i].name, constraint);
}
update_weak_position (view, frame, 150, 150);
}
void
constraint_view_remove_guide (ConstraintView *view,
GtkConstraintGuide *guide)
{
GtkConstraintLayout *layout;
GtkWidget *frame;
GtkConstraint *constraint;
const char *names[] = {
"left-constraint",
"top-constraint",
"width-constraint",
"height-constraint"
};
int i;
layout = GTK_CONSTRAINT_LAYOUT (gtk_widget_get_layout_manager (GTK_WIDGET (view)));
for (i = 0; i < G_N_ELEMENTS (names); i++)
{
constraint = (GtkConstraint*)g_object_get_data (G_OBJECT (guide), names[i]);
gtk_constraint_layout_remove_constraint (layout, constraint);
}
frame = (GtkWidget *)g_object_get_data (G_OBJECT (guide), "frame");
update_weak_position (view, frame, -100, -100);
gtk_widget_unparent (frame);
gtk_constraint_layout_remove_guide (layout, guide);
}
void
constraint_view_add_constraint (ConstraintView *view,
GtkConstraint *constraint)
{
GtkLayoutManager *manager;
manager = gtk_widget_get_layout_manager (GTK_WIDGET (view));
gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (manager),
g_object_ref (constraint));
}
void
constraint_view_remove_constraint (ConstraintView *view,
GtkConstraint *constraint)
{
GtkLayoutManager *manager;
manager = gtk_widget_get_layout_manager (GTK_WIDGET (view));
gtk_constraint_layout_remove_constraint (GTK_CONSTRAINT_LAYOUT (manager),
constraint);
}
GListModel *
constraint_view_get_model (ConstraintView *view)
{
return view->model;
}

View File

@@ -0,0 +1,44 @@
/*
* Copyright © 2019 Red Hat, Inc
*
* 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: Matthias Clasen
*/
#pragma once
#include <gtk/gtk.h>
#define CONSTRAINT_VIEW_TYPE (constraint_view_get_type ())
G_DECLARE_FINAL_TYPE (ConstraintView, constraint_view, CONSTRAINT, VIEW, GtkWidget)
ConstraintView * constraint_view_new (void);
void constraint_view_add_child (ConstraintView *view,
const char *name);
void constraint_view_remove_child (ConstraintView *view,
GtkWidget *child);
void constraint_view_add_guide (ConstraintView *view,
GtkConstraintGuide *guide);
void constraint_view_remove_guide (ConstraintView *view,
GtkConstraintGuide *guide);
void constraint_view_guide_changed (ConstraintView *view,
GtkConstraintGuide *guide);
void constraint_view_add_constraint (ConstraintView *view,
GtkConstraint *constraint);
void constraint_view_remove_constraint (ConstraintView *view,
GtkConstraint *constraint);
GListModel * constraint_view_get_model (ConstraintView *view);

View File

@@ -0,0 +1,411 @@
/*
* Copyright © 2019 Red Hat, Inc.
*
* 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: Matthias Clasen
*/
#include "config.h"
#include "guide-editor.h"
struct _GuideEditor
{
GtkWidget parent_instance;
GtkWidget *grid;
GtkWidget *name;
GtkWidget *min_width;
GtkWidget *min_height;
GtkWidget *nat_width;
GtkWidget *nat_height;
GtkWidget *max_width;
GtkWidget *max_height;
GtkWidget *strength;
GtkWidget *button;
GtkConstraintGuide *guide;
gboolean constructed;
};
enum {
PROP_GUIDE = 1,
LAST_PROP
};
static GParamSpec *pspecs[LAST_PROP];
enum {
DONE,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL];
G_DEFINE_TYPE(GuideEditor, guide_editor, GTK_TYPE_WIDGET);
static void
guide_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 GtkConstraintStrength
get_strength (const char *id)
{
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;
}
const char *
get_strength_nick (GtkConstraintStrength strength)
{
GEnumClass *class = g_type_class_ref (GTK_TYPE_CONSTRAINT_STRENGTH);
GEnumValue *value = g_enum_get_value (class, strength);
const char *nick = value->value_nick;
g_type_class_unref (class);
return nick;
}
void
guide_editor_serialize_guide (GString *str,
int indent,
GtkConstraintGuide *guide)
{
int min_width, min_height;
int nat_width, nat_height;
int max_width, max_height;
const char *name;
const char *strength;
gtk_constraint_guide_get_min_size (guide, &min_width, &min_height);
gtk_constraint_guide_get_nat_size (guide, &nat_width, &nat_height);
gtk_constraint_guide_get_max_size (guide, &max_width, &max_height);
name = gtk_constraint_guide_get_name (guide);
strength = get_strength_nick (gtk_constraint_guide_get_strength (guide));
g_string_append_printf (str, "%*s<guide min-width=\"%d\" min-height=\"%d\"\n", indent, "", min_width, min_height);
g_string_append_printf (str, "%*s nat-width=\"%d\" nat-height=\"%d\"\n", indent, "", nat_width, nat_height);
g_string_append_printf (str, "%*s max-width=\"%d\" max-height=\"%d\"\n", indent, "", max_width, max_height);
g_string_append_printf (str, "%*s name=\"%s\" strength=\"%s\" />\n", indent, "", name, strength);
}
static void
create_guide (GtkButton *button,
GuideEditor *editor)
{
const char *id;
int strength;
const char *name;
int w, h;
GtkConstraintGuide *guide;
if (editor->guide)
guide = g_object_ref (editor->guide);
else
guide = gtk_constraint_guide_new ();
name = gtk_editable_get_text (GTK_EDITABLE (editor->name));
gtk_constraint_guide_set_name (guide, name);
w = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (editor->min_width));
h = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (editor->min_height));
gtk_constraint_guide_set_min_size (guide, w, h);
w = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (editor->nat_width));
h = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (editor->nat_height));
gtk_constraint_guide_set_nat_size (guide, w, h);
w = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (editor->max_width));
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_combo_box_get_active_id (GTK_COMBO_BOX (editor->strength));
strength = get_strength (id);
gtk_constraint_guide_set_strength (guide, strength);
g_signal_emit (editor, signals[DONE], 0, guide);
g_object_unref (guide);
}
static void
guide_editor_init (GuideEditor *editor)
{
gtk_widget_init_template (GTK_WIDGET (editor));
}
static int guide_counter;
static int
min_input (GtkSpinButton *spin_button,
double *new_val)
{
if (strcmp (gtk_editable_get_text (GTK_EDITABLE (spin_button)), "") == 0)
{
*new_val = 0.0;
return TRUE;
}
return FALSE;
}
static int
max_input (GtkSpinButton *spin_button,
double *new_val)
{
if (strcmp (gtk_editable_get_text (GTK_EDITABLE (spin_button)), "") == 0)
{
*new_val = G_MAXINT;
return TRUE;
}
return FALSE;
}
static gboolean
min_output (GtkSpinButton *spin_button)
{
GtkAdjustment *adjustment;
double value;
GtkWidget *box, *text;
adjustment = gtk_spin_button_get_adjustment (spin_button);
value = gtk_adjustment_get_value (adjustment);
box = gtk_widget_get_first_child (GTK_WIDGET (spin_button));
text = gtk_widget_get_first_child (box);
if (value == 0.0)
{
gtk_editable_set_text (GTK_EDITABLE (spin_button), "");
gtk_text_set_placeholder_text (GTK_TEXT (text), "unset");
return TRUE;
}
else
{
gtk_text_set_placeholder_text (GTK_TEXT (text), "");
return FALSE;
}
}
static gboolean
max_output (GtkSpinButton *spin_button)
{
GtkAdjustment *adjustment;
double value;
GtkWidget *box, *text;
adjustment = gtk_spin_button_get_adjustment (spin_button);
value = gtk_adjustment_get_value (adjustment);
box = gtk_widget_get_first_child (GTK_WIDGET (spin_button));
text = gtk_widget_get_first_child (box);
if (value == (double)G_MAXINT)
{
gtk_editable_set_text (GTK_EDITABLE (spin_button), "");
gtk_text_set_placeholder_text (GTK_TEXT (text), "unset");
return TRUE;
}
else
{
gtk_text_set_placeholder_text (GTK_TEXT (text), "");
return FALSE;
}
}
static void
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_width, "output", G_CALLBACK (min_output), NULL);
g_signal_connect (editor->min_height, "input", G_CALLBACK (min_input), NULL);
g_signal_connect (editor->min_height, "output", G_CALLBACK (min_output), NULL);
g_signal_connect (editor->max_width, "input", G_CALLBACK (max_input), NULL);
g_signal_connect (editor->max_width, "output", G_CALLBACK (max_output), NULL);
g_signal_connect (editor->max_height, "input", G_CALLBACK (max_input), NULL);
g_signal_connect (editor->max_height, "output", G_CALLBACK (max_output), NULL);
if (editor->guide)
{
GtkConstraintStrength strength;
const char *nick;
int w, h;
nick = gtk_constraint_guide_get_name (editor->guide);
if (nick)
gtk_editable_set_text (GTK_EDITABLE (editor->name), nick);
gtk_constraint_guide_get_min_size (editor->guide, &w, &h);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->min_width), w);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->min_height), h);
gtk_constraint_guide_get_nat_size (editor->guide, &w, &h);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->nat_width), w);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->nat_height), h);
gtk_constraint_guide_get_max_size (editor->guide, &w, &h);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->max_width), w);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->max_height), h);
strength = gtk_constraint_guide_get_strength (editor->guide);
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
{
char *name;
guide_counter++;
name = g_strdup_printf ("Guide %d", guide_counter);
gtk_editable_set_text (GTK_EDITABLE (editor->name), name);
g_free (name);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->min_width), 0.0);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->min_height), 0.0);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->nat_width), 0.0);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->nat_height), 0.0);
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_combo_box_set_active_id (GTK_COMBO_BOX (editor->strength), "medium");
gtk_button_set_label (GTK_BUTTON (editor->button), "Create");
}
editor->constructed = TRUE;
}
static void
guide_editor_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GuideEditor *self = GUIDE_EDITOR (object);
switch (property_id)
{
case PROP_GUIDE:
self->guide = g_value_dup_object (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
}
static void
guide_editor_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GuideEditor *self = GUIDE_EDITOR (object);
switch (property_id)
{
case PROP_GUIDE:
g_value_set_object (value, self->guide);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
}
static void
guide_editor_dispose (GObject *object)
{
GuideEditor *self = (GuideEditor *)object;
g_clear_pointer (&self->grid, gtk_widget_unparent);
g_clear_object (&self->guide);
G_OBJECT_CLASS (guide_editor_parent_class)->dispose (object);
}
static void
guide_editor_class_init (GuideEditorClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
object_class->constructed = guide_editor_constructed;
object_class->dispose = guide_editor_dispose;
object_class->set_property = guide_editor_set_property;
object_class->get_property = guide_editor_get_property;
pspecs[PROP_GUIDE] =
g_param_spec_object ("guide", "guide", "guide",
GTK_TYPE_CONSTRAINT_GUIDE,
G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY);
g_object_class_install_properties (object_class, LAST_PROP, pspecs);
signals[DONE] =
g_signal_new ("done",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
NULL,
G_TYPE_NONE, 1, GTK_TYPE_CONSTRAINT_GUIDE);
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
gtk_widget_class_set_template_from_resource (widget_class,
"/org/gtk/gtk4/constraint-editor/guide-editor.ui");
gtk_widget_class_bind_template_child (widget_class, GuideEditor, grid);
gtk_widget_class_bind_template_child (widget_class, GuideEditor, name);
gtk_widget_class_bind_template_child (widget_class, GuideEditor, min_width);
gtk_widget_class_bind_template_child (widget_class, GuideEditor, min_height);
gtk_widget_class_bind_template_child (widget_class, GuideEditor, nat_width);
gtk_widget_class_bind_template_child (widget_class, GuideEditor, nat_height);
gtk_widget_class_bind_template_child (widget_class, GuideEditor, max_width);
gtk_widget_class_bind_template_child (widget_class, GuideEditor, max_height);
gtk_widget_class_bind_template_child (widget_class, GuideEditor, strength);
gtk_widget_class_bind_template_child (widget_class, GuideEditor, button);
gtk_widget_class_bind_template_callback (widget_class, create_guide);
}
GuideEditor *
guide_editor_new (GtkConstraintGuide *guide)
{
return g_object_new (GUIDE_EDITOR_TYPE,
"guide", guide,
NULL);
}

View File

@@ -0,0 +1,32 @@
/*
* Copyright © 2019 Red Hat, Inc
*
* 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: Matthias Clasen
*/
#pragma once
#include <gtk/gtk.h>
#define GUIDE_EDITOR_TYPE (guide_editor_get_type ())
G_DECLARE_FINAL_TYPE (GuideEditor, guide_editor, GUIDE, EDITOR, GtkWidget)
GuideEditor * guide_editor_new (GtkConstraintGuide *guide);
void guide_editor_serialize_guide (GString *str,
int indent,
GtkConstraintGuide *guide);

View File

@@ -0,0 +1,188 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkAdjustment" id="min_width_adj">
<property name="lower">0</property>
<property name="upper">2147483647</property>
<property name="step-increment">1</property>
<property name="page-increment">10</property>
<property name="page-size">0</property>
</object>
<object class="GtkAdjustment" id="min_height_adj">
<property name="lower">0</property>
<property name="upper">2147483647</property>
<property name="step-increment">1</property>
<property name="page-increment">10</property>
<property name="page-size">0</property>
</object>
<object class="GtkAdjustment" id="nat_width_adj">
<property name="lower">0</property>
<property name="upper">2147483647</property>
<property name="step-increment">1</property>
<property name="page-increment">10</property>
<property name="page-size">0</property>
</object>
<object class="GtkAdjustment" id="nat_height_adj">
<property name="lower">0</property>
<property name="upper">2147483647</property>
<property name="step-increment">1</property>
<property name="page-increment">10</property>
<property name="page-size">0</property>
</object>
<object class="GtkAdjustment" id="max_width_adj">
<property name="lower">0</property>
<property name="upper">2147483647</property>
<property name="step-increment">1</property>
<property name="page-increment">10</property>
<property name="page-size">0</property>
</object>
<object class="GtkAdjustment" id="max_height_adj">
<property name="lower">0</property>
<property name="upper">2147483647</property>
<property name="step-increment">1</property>
<property name="page-increment">10</property>
<property name="page-size">0</property>
</object>
<template class="GuideEditor" parent="GtkWidget">
<child>
<object class="GtkGrid" id="grid">
<property name="margin">20</property>
<property name="row-spacing">10</property>
<property name="column-spacing">10</property>
<child>
<object class="GtkLabel">
<property name="label">Name</property>
<layout>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</layout>
</object>
</child>
<child>
<object class="GtkEntry" id="name">
<property name="max-width-chars">20</property>
<layout>
<property name="left-attach">1</property>
<property name="top-attach">0</property>
<property name="column-span">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Min Size</property>
<layout>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkSpinButton" id="min_width">
<property name="adjustment">min_width_adj</property>
<property name="max-width-chars">5</property>
<layout>
<property name="left-attach">1</property>
<property name="top-attach">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkSpinButton" id="min_height">
<property name="adjustment">min_height_adj</property>
<property name="max-width-chars">5</property>
<layout>
<property name="left-attach">2</property>
<property name="top-attach">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Nat Size</property>
<layout>
<property name="left-attach">0</property>
<property name="top-attach">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkSpinButton" id="nat_width">
<property name="adjustment">nat_width_adj</property>
<property name="max-width-chars">5</property>
<layout>
<property name="left-attach">1</property>
<property name="top-attach">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkSpinButton" id="nat_height">
<property name="adjustment">nat_height_adj</property>
<property name="max-width-chars">5</property>
<layout>
<property name="left-attach">2</property>
<property name="top-attach">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Max Size</property>
<layout>
<property name="left-attach">0</property>
<property name="top-attach">3</property>
</layout>
</object>
</child>
<child>
<object class="GtkSpinButton" id="max_width">
<property name="adjustment">max_width_adj</property>
<property name="max-width-chars">5</property>
<layout>
<property name="left-attach">1</property>
<property name="top-attach">3</property>
</layout>
</object>
</child>
<child>
<object class="GtkSpinButton" id="max_height">
<property name="adjustment">max_height_adj</property>
<property name="max-width-chars">5</property>
<layout>
<property name="left-attach">2</property>
<property name="top-attach">3</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Strength</property>
<layout>
<property name="left-attach">0</property>
<property name="top-attach">4</property>
</layout>
</object>
</child>
<child>
<object class="GtkComboBoxText" id="strength">
<layout>
<property name="left-attach">1</property>
<property name="top-attach">4</property>
<property name="column-span">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkButton" id="button">
<property name="label">Create</property>
<signal name="clicked" handler="create_guide"/>
<layout>
<property name="left-attach">2</property>
<property name="top-attach">5</property>
</layout>
</object>
</child>
</object>
</child>
</template>
</interface>

View File

@@ -0,0 +1,28 @@
/*
* Copyright © 2019 Red Hat, Inc.
*
* 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: Matthias Clasen <mclasen@redhat.com>
*/
#include "config.h"
#include <constraint-editor-application.h>
int
main (int argc, char *argv[])
{
return g_application_run (G_APPLICATION (constraint_editor_application_new ()), argc, argv);
}

View File

@@ -0,0 +1,20 @@
constraint_editor_sources = [
'main.c',
'constraint-editor-application.c',
'constraint-editor-window.c',
'constraint-view.c',
'constraint-editor.c',
'guide-editor.c',
]
constraint_editor_resources = gnome.compile_resources('constraint_editor_resources',
'constraint-editor.gresource.xml',
source_dir: '.')
executable('gtk4-constraint-editor',
constraint_editor_sources, constraint_editor_resources,
dependencies: libgtk_dep,
include_directories: confinc,
gui_app: true,
link_args: extra_demo_ldflags,
install: false)

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

@@ -0,0 +1,248 @@
/*
* 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");
gtk_builder_connect_signals (builder, NULL);
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">
<child>
<object class="GtkLabel">
<property name="label" bind-source="GtkListItem" bind-property="position"></property>
<property name="margin">6</property>
</object>
</child>
</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,79 @@
/* 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;
#if 0
static void
create_listitem (GtkListItem *item, gpointer user_data)
{
GtkWidget *label;
label = gtk_label_new (NULL);
g_object_set (label, "margin", 6, NULL); /* omg, why do we need to do this?! */
gtk_label_set_xalign (GTK_LABEL (label), 0);
gtk_container_add (GTK_CONTAINER (item), label);
}
static void
bind_listitem (GtkListItem *item, gpointer user_data)
{
GtkAward *award = gtk_list_item_get_item (item);
gtk_label_set_text (GTK_LABEL (gtk_bin_get_child (GTK_BIN (item))),
gtk_award_get_title (award));
}
#endif
GtkWidget *
do_awardview (GtkWidget *do_widget)
{
if (!window)
{
GtkWidget *sw, *listview;
GListModel *list;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
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_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed), &window);
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_container_add (GTK_CONTAINER (window), sw);
#if 0
listview = gtk_list_view_new ();
gtk_list_view_set_functions (GTK_LIST_VIEW (listview),
create_listitem,
bind_listitem,
NULL, NULL);
#else
listview = gtk_list_view_new_with_factory (
gtk_builder_list_item_factory_new_from_resource ("/awardview/awardlistitem.ui"));
#endif
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_container_add (GTK_CONTAINER (sw), listview);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_widget_destroy (window);
return window;
}

View File

@@ -110,7 +110,7 @@ get_image_paintable (GtkImage *image)
icon_info = gtk_icon_theme_lookup_icon (icon_theme, icon_name, 48, GTK_ICON_LOOKUP_GENERIC_FALLBACK);
if (icon_info == NULL)
return NULL;
return GDK_PAINTABLE (gtk_icon_info_load_texture (icon_info));
return gtk_icon_info_load_icon (icon_info, NULL);
default:
g_warning ("Image storage type %d not handled",
gtk_image_get_storage_type (image));

View File

@@ -0,0 +1,289 @@
/* Constraints/Simple
*
* GtkConstraintLayout provides a layout manager that uses relations
* between widgets (also known as "constraints") to compute the position
* and size of each child.
*/
#include <glib/gi18n.h>
#include <gtk/gtk.h>
G_DECLARE_FINAL_TYPE (SimpleGrid, simple_grid, SIMPLE, GRID, GtkWidget)
struct _SimpleGrid
{
GtkWidget parent_instance;
GtkWidget *button1, *button2;
GtkWidget *button3;
};
G_DEFINE_TYPE (SimpleGrid, simple_grid, GTK_TYPE_WIDGET)
static void
simple_grid_destroy (GtkWidget *widget)
{
SimpleGrid *self = SIMPLE_GRID (widget);
g_clear_pointer (&self->button1, gtk_widget_destroy);
g_clear_pointer (&self->button2, gtk_widget_destroy);
g_clear_pointer (&self->button3, gtk_widget_destroy);
GTK_WIDGET_CLASS (simple_grid_parent_class)->destroy (widget);
}
static void
simple_grid_class_init (SimpleGridClass *klass)
{
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
widget_class->destroy = simple_grid_destroy;
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_CONSTRAINT_LAYOUT);
}
/* Layout:
*
* +-------------------------------------+
* | +-----------++-------++-----------+ |
* | | Child 1 || Space || Child 2 | |
* | +-----------++-------++-----------+ |
* | +---------------------------------+ |
* | | Child 3 | |
* | +---------------------------------+ |
* +-------------------------------------+
*
* Constraints:
*
* super.start = child1.start - 8
* child1.width = child2.width
* child1.end = space.start
* space.end = child2.start
* 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
*
* To add some flexibility, we make the space
* stretchable:
*
* space.width >= 10
* space.width = 100
* space.width <= 200
*/
static void
build_constraints (SimpleGrid *self,
GtkConstraintLayout *manager)
{
GtkConstraintGuide *guide;
guide = gtk_constraint_guide_new ();
gtk_constraint_guide_set_name (guide, "space");
gtk_constraint_guide_set_min_size (guide, 10, 10);
gtk_constraint_guide_set_nat_size (guide, 100, 10);
gtk_constraint_guide_set_max_size (guide, 200, 20);
gtk_constraint_guide_set_strength (guide, GTK_CONSTRAINT_STRENGTH_STRONG);
gtk_constraint_layout_add_guide (manager, guide);
gtk_constraint_layout_add_constraint (manager,
gtk_constraint_new_constant (GTK_CONSTRAINT_TARGET (self->button1),
GTK_CONSTRAINT_ATTRIBUTE_WIDTH,
GTK_CONSTRAINT_RELATION_LE,
200.0,
GTK_CONSTRAINT_STRENGTH_REQUIRED));
gtk_constraint_layout_add_constraint (manager,
gtk_constraint_new (NULL,
GTK_CONSTRAINT_ATTRIBUTE_START,
GTK_CONSTRAINT_RELATION_EQ,
self->button1,
GTK_CONSTRAINT_ATTRIBUTE_START,
1.0,
-8.0,
GTK_CONSTRAINT_STRENGTH_REQUIRED));
gtk_constraint_layout_add_constraint (manager,
gtk_constraint_new (self->button1,
GTK_CONSTRAINT_ATTRIBUTE_WIDTH,
GTK_CONSTRAINT_RELATION_EQ,
self->button2,
GTK_CONSTRAINT_ATTRIBUTE_WIDTH,
1.0,
0.0,
GTK_CONSTRAINT_STRENGTH_REQUIRED));
gtk_constraint_layout_add_constraint (manager,
gtk_constraint_new (self->button1,
GTK_CONSTRAINT_ATTRIBUTE_END,
GTK_CONSTRAINT_RELATION_EQ,
guide,
GTK_CONSTRAINT_ATTRIBUTE_START,
1.0,
0.0,
GTK_CONSTRAINT_STRENGTH_REQUIRED));
gtk_constraint_layout_add_constraint (manager,
gtk_constraint_new (guide,
GTK_CONSTRAINT_ATTRIBUTE_END,
GTK_CONSTRAINT_RELATION_EQ,
self->button2,
GTK_CONSTRAINT_ATTRIBUTE_START,
1.0,
0.0,
GTK_CONSTRAINT_STRENGTH_REQUIRED));
gtk_constraint_layout_add_constraint (manager,
gtk_constraint_new (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,
self->button3,
GTK_CONSTRAINT_ATTRIBUTE_START,
1.0,
-8.0,
GTK_CONSTRAINT_STRENGTH_REQUIRED));
gtk_constraint_layout_add_constraint (manager,
gtk_constraint_new (self->button3,
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_TOP,
GTK_CONSTRAINT_RELATION_EQ,
self->button1,
GTK_CONSTRAINT_ATTRIBUTE_TOP,
1.0,
-8.0,
GTK_CONSTRAINT_STRENGTH_REQUIRED));
gtk_constraint_layout_add_constraint (manager,
gtk_constraint_new (NULL,
GTK_CONSTRAINT_ATTRIBUTE_TOP,
GTK_CONSTRAINT_RELATION_EQ,
self->button2,
GTK_CONSTRAINT_ATTRIBUTE_TOP,
1.0,
-8.0,
GTK_CONSTRAINT_STRENGTH_REQUIRED));
gtk_constraint_layout_add_constraint (manager,
gtk_constraint_new (self->button1,
GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
GTK_CONSTRAINT_RELATION_EQ,
self->button3,
GTK_CONSTRAINT_ATTRIBUTE_TOP,
1.0,
-12.0,
GTK_CONSTRAINT_STRENGTH_REQUIRED));
gtk_constraint_layout_add_constraint (manager,
gtk_constraint_new (self->button2,
GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
GTK_CONSTRAINT_RELATION_EQ,
self->button3,
GTK_CONSTRAINT_ATTRIBUTE_TOP,
1.0,
-12.0,
GTK_CONSTRAINT_STRENGTH_REQUIRED));
gtk_constraint_layout_add_constraint (manager,
gtk_constraint_new (self->button3,
GTK_CONSTRAINT_ATTRIBUTE_HEIGHT,
GTK_CONSTRAINT_RELATION_EQ,
self->button1,
GTK_CONSTRAINT_ATTRIBUTE_HEIGHT,
1.0,
0.0,
GTK_CONSTRAINT_STRENGTH_REQUIRED));
gtk_constraint_layout_add_constraint (manager,
gtk_constraint_new (self->button3,
GTK_CONSTRAINT_ATTRIBUTE_HEIGHT,
GTK_CONSTRAINT_RELATION_EQ,
self->button2,
GTK_CONSTRAINT_ATTRIBUTE_HEIGHT,
1.0,
0.0,
GTK_CONSTRAINT_STRENGTH_REQUIRED));
gtk_constraint_layout_add_constraint (manager,
gtk_constraint_new (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
simple_grid_init (SimpleGrid *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 (GtkWidget *do_widget)
{
static GtkWidget *window;
if (!window)
{
GtkWidget *header, *box, *grid, *button;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
header = gtk_header_bar_new ();
gtk_header_bar_set_title (GTK_HEADER_BAR (header), "Constraints");
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), FALSE);
gtk_window_set_titlebar (GTK_WINDOW (window), header);
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed), &window);
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
gtk_container_add (GTK_CONTAINER (window), box);
grid = g_object_new (simple_grid_get_type (), NULL);
gtk_widget_set_hexpand (grid, TRUE);
gtk_widget_set_vexpand (grid, TRUE);
gtk_container_add (GTK_CONTAINER (box), grid);
button = gtk_button_new_with_label ("Close");
gtk_container_add (GTK_CONTAINER (box), button);
gtk_widget_set_hexpand (grid, TRUE);
g_signal_connect_swapped (button, "clicked",
G_CALLBACK (gtk_widget_destroy), window);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_widget_destroy (window);
return 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_destroy (GtkWidget *widget)
{
InteractiveGrid *self = INTERACTIVE_GRID (widget);
g_clear_pointer (&self->button1, gtk_widget_destroy);
g_clear_pointer (&self->button2, gtk_widget_destroy);
g_clear_pointer (&self->button3, gtk_widget_destroy);
GTK_WIDGET_CLASS (interactive_grid_parent_class)->destroy (widget);
}
static void
interactive_grid_class_init (InteractiveGridClass *klass)
{
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
widget_class->destroy = interactive_grid_destroy;
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_TOPLEVEL);
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
header = gtk_header_bar_new ();
gtk_header_bar_set_title (GTK_HEADER_BAR (header), "Constraints");
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), FALSE);
gtk_window_set_titlebar (GTK_WINDOW (window), header);
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed), &window);
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
gtk_container_add (GTK_CONTAINER (window), box);
grid = g_object_new (interactive_grid_get_type (), NULL);
gtk_widget_set_hexpand (grid, TRUE);
gtk_widget_set_vexpand (grid, TRUE);
gtk_container_add (GTK_CONTAINER (box), grid);
button = gtk_button_new_with_label ("Close");
gtk_container_add (GTK_CONTAINER (box), button);
gtk_widget_set_hexpand (grid, TRUE);
g_signal_connect_swapped (button, "clicked",
G_CALLBACK (gtk_widget_destroy), window);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_widget_destroy (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_destroy (GtkWidget *widget)
{
VflGrid *self = VFL_GRID (widget);
g_clear_pointer (&self->button1, gtk_widget_destroy);
g_clear_pointer (&self->button2, gtk_widget_destroy);
g_clear_pointer (&self->button3, gtk_widget_destroy);
GTK_WIDGET_CLASS (vfl_grid_parent_class)->destroy (widget);
}
static void
vfl_grid_class_init (VflGridClass *klass)
{
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
widget_class->destroy = vfl_grid_destroy;
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_TOPLEVEL);
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
header = gtk_header_bar_new ();
gtk_header_bar_set_title (GTK_HEADER_BAR (header), "Constraints");
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), FALSE);
gtk_window_set_titlebar (GTK_WINDOW (window), header);
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed), &window);
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
gtk_container_add (GTK_CONTAINER (window), box);
grid = g_object_new (vfl_grid_get_type (), NULL);
gtk_widget_set_hexpand (grid, TRUE);
gtk_widget_set_vexpand (grid, TRUE);
gtk_container_add (GTK_CONTAINER (box), grid);
button = gtk_button_new_with_label ("Close");
gtk_container_add (GTK_CONTAINER (box), button);
gtk_widget_set_hexpand (grid, TRUE);
g_signal_connect_swapped (button, "clicked",
G_CALLBACK (gtk_widget_destroy), window);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_widget_destroy (window);
return window;
}

View File

@@ -1,7 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/">
<file>awards.ui</file>
</gresource>
<gresource prefix="/ui">
<file preprocess="xml-stripblanks">main.ui</file>
<file preprocess="xml-stripblanks">main-listitem.ui</file>
<file preprocess="xml-stripblanks">appmenu.ui</file>
</gresource>
<gresource prefix="/application_demo">
@@ -9,6 +13,9 @@
<file>application.ui</file>
<file>menus.ui</file>
</gresource>
<gresource prefix="/awardview">
<file>awardlistitem.ui</file>
</gresource>
<gresource prefix="/builder">
<file>demo.ui</file>
</gresource>
@@ -104,10 +111,23 @@
<file>gtkfishbowl.c</file>
<file>gtkfishbowl.h</file>
</gresource>
<gresource prefix="/iconscroll">
<file>iconscroll.ui</file>
</gresource>
<gresource prefix="/iconview">
<file>gnome-fs-directory.png</file>
<file>gnome-fs-regular.png</file>
</gresource>
<gresource prefix="/listview_filebrowser">
<file>listview_filebrowser.ui</file>
</gresource>
<gresource prefix="/listview_minesweeper">
<file>listview_minesweeper.ui</file>
<file>listview_minesweeper_cell.ui</file>
</gresource>
<gresource prefix="/listview_weather">
<file compressed="true">listview_weather.txt</file>
</gresource>
<gresource prefix="/shortcuts">
<file>shortcuts.ui</file>
<file>shortcuts-builder.ui</file>
@@ -144,12 +164,16 @@
</gresource>
<gresource prefix="/sources">
<file>application_demo.c</file>
<file>awardview.c</file>
<file>assistant.c</file>
<file>builder.c</file>
<file>changedisplay.c</file>
<file>clipboard.c</file>
<file>colorsel.c</file>
<file>combobox.c</file>
<file>constraints.c</file>
<file>constraints2.c</file>
<file>constraints3.c</file>
<file>css_accordion.c</file>
<file>css_basics.c</file>
<file>css_blendmodes.c</file>
@@ -171,16 +195,21 @@
<file>foreigndrawing.c</file>
<file>font_features.c</file>
<file>fontplane.c</file>
<file>fontrendering.c</file>
<file>gestures.c</file>
<file>glarea.c</file>
<file>headerbar.c</file>
<file>hypertext.c</file>
<file>iconscroll.c</file>
<file>iconview.c</file>
<file>iconview_edit.c</file>
<file>images.c</file>
<file>infobar.c</file>
<file>links.c</file>
<file>listbox.c</file>
<file>listview_filebrowser.c</file>
<file>listview_settings.c</file>
<file>listview_weather.c</file>
<file>list_store.c</file>
<file>markup.c</file>
<file>menus.c</file>
@@ -278,6 +307,9 @@
<gresource prefix="/fixed">
<file>fixed.css</file>
</gresource>
<gresource prefix="/fontrendering">
<file>fontrendering.ui</file>
</gresource>
<gresource prefix="/org/gtk/Demo4">
<file>icons/16x16/actions/application-exit.png</file>
<file>icons/16x16/actions/document-new.png</file>

View File

@@ -129,13 +129,13 @@ demo_tagged_entry_size_allocate (GtkWidget *widget,
baseline);
}
static void
static gboolean
demo_tagged_entry_grab_focus (GtkWidget *widget)
{
DemoTaggedEntry *entry = DEMO_TAGGED_ENTRY (widget);
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
gtk_widget_grab_focus (priv->entry);
return gtk_widget_grab_focus (priv->entry);
}
static void

View File

@@ -52,7 +52,7 @@ do_expander (GtkWidget *do_widget)
area = gtk_message_dialog_get_message_area (GTK_MESSAGE_DIALOG (window));
label = gtk_widget_get_last_child (area);
gtk_label_set_line_wrap (GTK_LABEL (label), FALSE);
gtk_label_set_wrap (GTK_LABEL (label), FALSE);
gtk_widget_set_vexpand (label, FALSE);
expander = gtk_expander_new ("Details:");

View File

@@ -124,7 +124,7 @@ create_label (void)
{
GtkWidget *w = gtk_label_new ("pLorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.");
gtk_label_set_line_wrap (GTK_LABEL (w), TRUE);
gtk_label_set_wrap (GTK_LABEL (w), TRUE);
gtk_label_set_max_width_chars (GTK_LABEL (w), 100);
return w;
@@ -306,6 +306,7 @@ do_fishbowl (GtkWidget *do_widget)
G_CALLBACK (gtk_widget_destroyed), &window);
gtk_widget_realize (window);
g_object_unref (builder);
}
if (!gtk_widget_get_visible (window))

View File

@@ -28,22 +28,7 @@
</child>
<child type="end">
<object class="GtkLabel">
<property name="label">fps</property>
</object>
</child>
<child type="end">
<object class="GtkLabel">
<property name="label" bind-source="bowl" bind-property="framerate-string"/>
</object>
</child>
<child type="end">
<object class="GtkLabel">
<property name="label">Icons, </property>
</object>
</child>
<child type="end">
<object class="GtkLabel">
<property name="label" bind-source="bowl" bind-property="count"/>
<binding name="label">bowl.count + " Icons, " + bowl.framerate + "fps"</binding>
</object>
</child>
<child type="end">

View File

@@ -0,0 +1,288 @@
/* Pango/Font rendering
*
* Demonstrates various aspects of font rendering.
*/
#include <gtk/gtk.h>
static GtkWidget *window = NULL;
static GtkWidget *font_button = NULL;
static GtkWidget *entry = NULL;
static GtkWidget *image = NULL;
static GtkWidget *hinting = NULL;
static GtkWidget *hint_metrics = NULL;
static GtkWidget *up_button = NULL;
static GtkWidget *down_button = NULL;
static GtkWidget *text_radio = NULL;
static GtkWidget *show_grid = NULL;
static GtkWidget *show_extents = NULL;
static PangoContext *context;
static int scale = 10;
static void
on_destroy (gpointer data)
{
window = NULL;
}
static void
update_image (void)
{
const char *text;
PangoFontDescription *desc;
PangoLayout *layout;
PangoRectangle ink, pink, logical;
int baseline;
cairo_surface_t *surface;
cairo_t *cr;
GdkPixbuf *pixbuf;
GdkPixbuf *pixbuf2;
const char *hint;
cairo_font_options_t *fopt;
cairo_hint_style_t hintstyle;
cairo_hint_metrics_t hintmetrics;
int i;
if (!context)
context = gtk_widget_create_pango_context (image);
text = gtk_editable_get_text (GTK_EDITABLE (entry));
desc = gtk_font_chooser_get_font_desc (GTK_FONT_CHOOSER (font_button));
fopt = cairo_font_options_copy (pango_cairo_context_get_font_options (context));
hint = gtk_combo_box_get_active_id (GTK_COMBO_BOX (hinting));
if (strcmp (hint, "none") == 0)
hintstyle = CAIRO_HINT_STYLE_NONE;
else if (strcmp (hint, "slight") == 0)
hintstyle = CAIRO_HINT_STYLE_SLIGHT;
else if (strcmp (hint, "medium") == 0)
hintstyle = CAIRO_HINT_STYLE_MEDIUM;
else if (strcmp (hint, "full") == 0)
hintstyle = CAIRO_HINT_STYLE_FULL;
else
hintstyle = CAIRO_HINT_STYLE_DEFAULT;
cairo_font_options_set_hint_style (fopt, hintstyle);
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (hint_metrics)))
hintmetrics = CAIRO_HINT_METRICS_ON;
else
hintmetrics = CAIRO_HINT_METRICS_OFF;
cairo_font_options_set_hint_metrics (fopt, hintmetrics);
pango_cairo_context_set_font_options (context, fopt);
cairo_font_options_destroy (fopt);
pango_context_changed (context);
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (text_radio)))
{
layout = pango_layout_new (context);
pango_layout_set_font_description (layout, desc);
pango_layout_set_text (layout, text, -1);
pango_layout_get_extents (layout, &ink, &logical);
pink = ink;
baseline = pango_layout_get_baseline (layout);
pango_extents_to_pixels (&ink, NULL);
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, ink.width + 20, ink.height + 20);
cr = cairo_create (surface);
cairo_set_source_rgb (cr, 1, 1, 1);
cairo_paint (cr);
cairo_set_source_rgb (cr, 0, 0, 0);
cairo_move_to (cr, 10, 10);
pango_cairo_show_layout (cr, layout);
cairo_destroy (cr);
g_object_unref (layout);
pixbuf = gdk_pixbuf_get_from_surface (surface, 0, 0, cairo_image_surface_get_width (surface), cairo_image_surface_get_height (surface));
pixbuf2 = gdk_pixbuf_scale_simple (pixbuf, gdk_pixbuf_get_width (pixbuf) * scale, gdk_pixbuf_get_height (pixbuf) * scale, GDK_INTERP_NEAREST);
g_object_unref (pixbuf);
cairo_surface_destroy (surface);
surface = cairo_image_surface_create_for_data (gdk_pixbuf_get_pixels (pixbuf2),
CAIRO_FORMAT_ARGB32,
gdk_pixbuf_get_width (pixbuf2),
gdk_pixbuf_get_height (pixbuf2),
gdk_pixbuf_get_rowstride (pixbuf2));
cr = cairo_create (surface);
cairo_set_line_width (cr, 1);
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (show_grid)))
{
cairo_set_source_rgba (cr, 0.2, 0, 0, 0.2);
for (i = 1; i < ink.height + 20; i++)
{
cairo_move_to (cr, 0, scale * i - 0.5);
cairo_line_to (cr, scale * (ink.width + 20), scale * i - 0.5);
cairo_stroke (cr);
}
for (i = 1; i < ink.width + 20; i++)
{
cairo_move_to (cr, scale * i - 0.5, 0);
cairo_line_to (cr, scale * i - 0.5, scale * (ink.height + 20));
cairo_stroke (cr);
}
}
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (show_extents)))
{
cairo_set_source_rgba (cr, 0, 0, 1, 1);
cairo_rectangle (cr,
scale * (10 + pango_units_to_double (logical.x)) - 0.5,
scale * (10 + pango_units_to_double (logical.y)) - 0.5,
scale * pango_units_to_double (logical.width) + 1,
scale * pango_units_to_double (logical.height) + 1);
cairo_stroke (cr);
cairo_move_to (cr, scale * (10 + pango_units_to_double (logical.x)) - 0.5,
scale * (10 + pango_units_to_double (baseline)) - 0.5);
cairo_line_to (cr, scale * (10 + pango_units_to_double (logical.x + logical.width)) + 1,
scale * (10 + pango_units_to_double (baseline)) - 0.5);
cairo_stroke (cr);
cairo_set_source_rgba (cr, 1, 0, 0, 1);
cairo_rectangle (cr,
scale * (10 + pango_units_to_double (pink.x)) + 0.5,
scale * (10 + pango_units_to_double (pink.y)) + 0.5,
scale * pango_units_to_double (pink.width) - 1,
scale * pango_units_to_double (pink.height) - 1);
cairo_stroke (cr);
}
cairo_surface_destroy (surface);
cairo_destroy (cr);
}
else
{
PangoLayoutIter *iter;
PangoLayoutRun *run;
PangoGlyphInfo *g;
int i, j;
layout = pango_layout_new (context);
pango_layout_set_font_description (layout, desc);
pango_layout_set_text (layout, "aaaa", -1);
pango_layout_get_extents (layout, &ink, &logical);
pango_extents_to_pixels (&logical, NULL);
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, logical.width * 3 / 2, 4*logical.height);
cr = cairo_create (surface);
cairo_set_source_rgb (cr, 1, 1, 1);
cairo_paint (cr);
iter = pango_layout_get_iter (layout);
run = pango_layout_iter_get_run (iter);
cairo_set_source_rgb (cr, 0, 0, 0);
for (i = 0; i < 4; i++)
{
g = &(run->glyphs->glyphs[i]);
g->geometry.width = PANGO_UNITS_ROUND (g->geometry.width * 3 / 2);
}
for (j = 0; j < 4; j++)
{
for (i = 0; i < 4; i++)
{
g = &(run->glyphs->glyphs[i]);
g->geometry.x_offset = i * (PANGO_SCALE / 4);
g->geometry.y_offset = j * (PANGO_SCALE / 4);
}
cairo_move_to (cr, 0, j * logical.height);
pango_cairo_show_layout (cr, layout);
}
cairo_destroy (cr);
pango_layout_iter_free (iter);
g_object_unref (layout);
pixbuf = gdk_pixbuf_get_from_surface (surface, 0, 0, cairo_image_surface_get_width (surface), cairo_image_surface_get_height (surface));
pixbuf2 = gdk_pixbuf_scale_simple (pixbuf, gdk_pixbuf_get_width (pixbuf) * scale, gdk_pixbuf_get_height (pixbuf) * scale, GDK_INTERP_NEAREST);
g_object_unref (pixbuf);
cairo_surface_destroy (surface);
}
gtk_picture_set_pixbuf (GTK_PICTURE (image), pixbuf2);
g_object_unref (pixbuf2);
pango_font_description_free (desc);
}
static void
update_buttons (void)
{
gtk_widget_set_sensitive (up_button, scale < 32);
gtk_widget_set_sensitive (down_button, scale > 1);
}
static void
scale_up (void)
{
scale += 1;
update_buttons ();
update_image ();
}
static void
scale_down (void)
{
scale -= 1;
update_buttons ();
update_image ();
}
GtkWidget *
do_fontrendering (GtkWidget *do_widget)
{
if (!window)
{
GtkBuilder *builder;
builder = gtk_builder_new_from_resource ("/fontrendering/fontrendering.ui");
gtk_builder_connect_signals (builder, NULL);
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
g_signal_connect (window, "destroy",
G_CALLBACK (on_destroy), NULL);
g_object_set_data_full (G_OBJECT (window), "builder", builder, g_object_unref);
font_button = GTK_WIDGET (gtk_builder_get_object (builder, "font_button"));
up_button = GTK_WIDGET (gtk_builder_get_object (builder, "up_button"));
down_button = GTK_WIDGET (gtk_builder_get_object (builder, "down_button"));
entry = GTK_WIDGET (gtk_builder_get_object (builder, "entry"));
image = GTK_WIDGET (gtk_builder_get_object (builder, "image"));
hinting = GTK_WIDGET (gtk_builder_get_object (builder, "hinting"));
hint_metrics = GTK_WIDGET (gtk_builder_get_object (builder, "hint_metrics"));
text_radio = GTK_WIDGET (gtk_builder_get_object (builder, "text_radio"));
show_grid = GTK_WIDGET (gtk_builder_get_object (builder, "show_grid"));
show_extents = GTK_WIDGET (gtk_builder_get_object (builder, "show_extents"));
g_signal_connect (up_button, "clicked", G_CALLBACK (scale_up), NULL);
g_signal_connect (down_button, "clicked", G_CALLBACK (scale_down), NULL);
g_signal_connect (entry, "notify::text", G_CALLBACK (update_image), NULL);
g_signal_connect (font_button, "notify::font-desc", G_CALLBACK (update_image), NULL);
g_signal_connect (hinting, "notify::active", G_CALLBACK (update_image), NULL);
g_signal_connect (hint_metrics, "notify::active", G_CALLBACK (update_image), NULL);
g_signal_connect (text_radio, "notify::active", G_CALLBACK (update_image), NULL);
g_signal_connect (show_grid, "notify::active", G_CALLBACK (update_image), NULL);
g_signal_connect (show_extents, "notify::active", G_CALLBACK (update_image), NULL);
update_image ();
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_widget_destroy (window);
return window;
}

View File

@@ -0,0 +1,215 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkAdjustment" id="scale_adj">
<property name="upper">24</property>
<property name="step-increment">1</property>
<property name="page-increment">4</property>
</object>
<object class="GtkWindow" id="window">
<property name="default-width">600</property>
<property name="default-height">300</property>
<property name="title">Font rendering</property>
<child>
<object class="GtkGrid">
<property name="margin-top">10</property>
<property name="row-spacing">10</property>
<property name="column-spacing">10</property>
<child>
<object class="GtkLabel">
<property name="margin-start">10</property>
<property name="label">Text</property>
<property name="xalign">1</property>
<style>
<class name="dim-label"/>
</style>
</object>
</child>
<child>
<object class="GtkEntry" id="entry">
<property name="text">Fonts render</property>
<layout>
<property name="left-attach">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="margin-start">10</property>
<property name="label">Font</property>
<property name="xalign">1</property>
<style>
<class name="dim-label"/>
</style>
<layout>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkFontButton" id="font_button">
<layout>
<property name="left-attach">1</property>
<property name="top-attach">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Hinting</property>
<property name="xalign">1</property>
<style>
<class name="dim-label"/>
</style>
<layout>
<property name="left-attach">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkComboBoxText" id="hinting">
<property name="active">0</property>
<property name="valign">center</property>
<items>
<item translatable="yes" id="none">None</item>
<item translatable="yes" id="slight">Slight</item>
<item translatable="yes" id="medium">Medium</item>
<item translatable="yes" id="full">Full</item>
</items>
<layout>
<property name="left-attach">3</property>
</layout>
</object>
</child>
<child>
<object class="GtkCheckButton" id="hint_metrics">
<child>
<object class="GtkLabel">
<property name="label">Hint Metrics</property>
<style>
<class name="dim-label"/>
</style>
</object>
</child>
<layout>
<property name="left-attach">3</property>
<property name="top-attach">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkCheckButton" id="show_extents">
<property name="active">1</property>
<child>
<object class="GtkLabel">
<property name="label">Show Extents</property>
<style>
<class name="dim-label"/>
</style>
</object>
</child>
<layout>
<property name="left-attach">4</property>
<property name="top-attach">0</property>
</layout>
</object>
</child>
<child>
<object class="GtkCheckButton" id="show_grid">
<property name="active">1</property>
<child>
<object class="GtkLabel">
<property name="label">Show Grid</property>
<style>
<class name="dim-label"/>
</style>
</object>
</child>
<layout>
<property name="left-attach">4</property>
<property name="top-attach">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkButton" id="up_button">
<property name="icon-name">list-add-symbolic</property>
<style>
<class name="circular"/>
</style>
<layout>
<property name="left-attach">5</property>
<property name="top-attach">0</property>
</layout>
</object>
</child>
<child>
<object class="GtkButton" id="down_button">
<property name="icon-name">list-remove-symbolic</property>
<style>
<class name="circular"/>
</style>
<layout>
<property name="left-attach">5</property>
<property name="top-attach">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="hexpand">1</property>
<layout>
<property name="left-attach">6</property>
</layout>
</object>
</child>
<child>
<object class="GtkBox">
<property name="orientation">horizontal</property>
<property name="halign">center</property>
<property name="valign">center</property>
<style><class name="linked"/></style>
<child>
<object class="GtkRadioButton" id="text_radio">
<property name="draw-indicator">0</property>
<property name="label">Text</property>
</object>
</child>
<child>
<object class="GtkRadioButton" id="grid_radio">
<property name="draw-indicator">0</property>
<property name="label">Grid</property>
<property name="group">text_radio</property>
</object>
</child>
<layout>
<property name="left-attach">0</property>
<property name="top-attach">3</property>
<property name="column-span">7</property>
</layout>
</object>
</child>
<child>
<object class="GtkScrolledWindow">
<property name="propagate-natural-height">1</property>
<property name="shadow-type">in</property>
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<child>
<object class="GtkPicture" id="image">
<property name="halign">center</property>
<property name="valign">center</property>
<property name="can-shrink">0</property>
</object>
</child>
<layout>
<property name="left-attach">0</property>
<property name="top-attach">4</property>
<property name="column-span">7</property>
</layout>
</object>
</child>
</object>
</child>
</object>
</interface>

View File

@@ -829,7 +829,6 @@ draw_spinbutton (GtkWidget *widget,
GtkStyleContext *down_context;
GtkIconTheme *icon_theme;
GtkIconInfo *icon_info;
GdkPixbuf *pixbuf;
GdkTexture *texture;
gint icon_width, icon_height, icon_size;
gint button_width;
@@ -857,26 +856,22 @@ draw_spinbutton (GtkWidget *widget,
"min-width", &icon_width, "min-height", &icon_height, NULL);
icon_size = MIN (icon_width, icon_height);
icon_info = gtk_icon_theme_lookup_icon (icon_theme, "list-add-symbolic", icon_size, 0);
pixbuf = gtk_icon_info_load_symbolic_for_context (icon_info, up_context, NULL, NULL);
texture = gdk_texture_new_for_pixbuf (pixbuf);
texture = GDK_TEXTURE (gtk_icon_info_load_symbolic_for_context (icon_info, up_context, NULL, NULL));
g_object_unref (icon_info);
draw_style_common (up_context, cr, x + width - button_width, y, button_width, *height,
&contents_x, &contents_y, &contents_width, &contents_height);
gtk_render_icon (up_context, cr, texture, contents_x, contents_y + (contents_height - icon_size) / 2);
g_object_unref (pixbuf);
g_object_unref (texture);
gtk_style_context_get (down_context,
"min-width", &icon_width, "min-height", &icon_height, NULL);
icon_size = MIN (icon_width, icon_height);
icon_info = gtk_icon_theme_lookup_icon (icon_theme, "list-remove-symbolic", icon_size, 0);
pixbuf = gtk_icon_info_load_symbolic_for_context (icon_info, down_context, NULL, NULL);
texture = gdk_texture_new_for_pixbuf (pixbuf);
texture = GDK_TEXTURE (gtk_icon_info_load_symbolic_for_context (icon_info, down_context, NULL, NULL));
g_object_unref (icon_info);
draw_style_common (down_context, cr, x + width - 2 * button_width, y, button_width, *height,
&contents_x, &contents_y, &contents_width, &contents_height);
gtk_render_icon (down_context, cr, texture, contents_x, contents_y + (contents_height - icon_size) / 2);
g_object_unref (pixbuf);
g_object_unref (texture);
g_object_unref (down_context);

View File

@@ -13,17 +13,16 @@ in_files = sys.argv[2:]
file_output = """
typedef GtkWidget *(*GDoDemoFunc) (GtkWidget *do_widget);
typedef struct _Demo Demo;
typedef struct _DemoData DemoData;
struct _Demo
struct _DemoData
{
gchar *name;
gchar *title;
gchar *filename;
char *name;
char *title;
char *filename;
GDoDemoFunc func;
Demo *children;
DemoData *children;
};
"""
# Demo = namedtuple('Demo', ['name', 'title', 'file', 'func'])
@@ -67,7 +66,7 @@ for demo in demos:
i = 0
for parent in parents:
id = parent_ids[i]
file_output += "\nDemo child" + str(id) + "[] = {\n"
file_output += "\nDemoData child" + str(id) + "[] = {\n"
# iterate over all demos and check if the name starts with the given parent name
for child in demos:
if child[1].startswith(parent + "/"):
@@ -82,7 +81,7 @@ for parent in parents:
# Sort demos by title
demos = sorted(demos, key=lambda x: x[1])
file_output += "\nDemo gtk_demos[] = {\n"
file_output += "\nDemoData gtk_demos[] = {\n"
for demo in demos:
# Do not generate one of these for demos with a parent demo
if "/" not in demo[1]:

View File

@@ -241,7 +241,7 @@ realize (GtkWidget *widget)
fragment_path = "/glarea/glarea-gl.fs.glsl";
}
init_buffers (&position_buffer, NULL);
init_buffers (NULL, &position_buffer);
init_shaders (vertex_path, fragment_path, &program, &mvp_location);
}

185
demos/gtk-demo/iconscroll.c Normal file
View File

@@ -0,0 +1,185 @@
/* Benchmark/Scrolling
*
* This demo scrolls a view with various content.
*/
#include <gtk/gtk.h>
static guint tick_cb;
static GtkAdjustment *adjustment;
static GtkWidget *window = NULL;
static GtkWidget *scrolledwindow;
static int selected;
#define N_WIDGET_TYPES 3
int increment = 5;
static gboolean
scroll_cb (GtkWidget *widget,
GdkFrameClock *frame_clock,
gpointer data)
{
double value;
value = gtk_adjustment_get_value (adjustment);
if (value + increment <= gtk_adjustment_get_lower (adjustment) ||
(value + increment >= gtk_adjustment_get_upper (adjustment) - gtk_adjustment_get_page_size (adjustment)))
increment = - increment;
gtk_adjustment_set_value (adjustment, value + increment);
return G_SOURCE_CONTINUE;
}
extern GtkWidget *create_icon (void);
static void
populate_icons (void)
{
GtkWidget *grid;
int top, left;
grid = gtk_grid_new ();
gtk_widget_set_halign (grid, GTK_ALIGN_CENTER);
g_object_set (grid, "margin", 10, NULL);
gtk_grid_set_row_spacing (GTK_GRID (grid), 10);
gtk_grid_set_column_spacing (GTK_GRID (grid), 10);
for (top = 0; top < 100; top++)
for (left = 0; left < 15; left++)
gtk_grid_attach (GTK_GRID (grid), create_icon (), left, top, 1, 1);
gtk_container_add (GTK_CONTAINER (scrolledwindow), grid);
}
static char *content;
static gsize content_len;
extern void fontify (GtkTextBuffer *buffer);
static void
populate_text (gboolean hilight)
{
GtkWidget *textview;
GtkTextBuffer *buffer;
if (!content)
{
GBytes *bytes;
bytes = g_resources_lookup_data ("/sources/font_features.c", 0, NULL);
content = g_bytes_unref_to_data (bytes, &content_len);
}
buffer = gtk_text_buffer_new (NULL);
gtk_text_buffer_set_text (buffer, content, (int)content_len);
if (hilight)
fontify (buffer);
textview = gtk_text_view_new ();
gtk_text_view_set_buffer (GTK_TEXT_VIEW (textview), buffer);
gtk_container_add (GTK_CONTAINER (scrolledwindow), textview);
}
static void
set_widget_type (int type)
{
if (tick_cb)
gtk_widget_remove_tick_callback (window, tick_cb);
if (gtk_bin_get_child (GTK_BIN (scrolledwindow)))
gtk_container_remove (GTK_CONTAINER (scrolledwindow),
gtk_bin_get_child (GTK_BIN (scrolledwindow)));
selected = type;
switch (selected)
{
case 0:
gtk_window_set_title (GTK_WINDOW (window), "Scrolling icons");
populate_icons ();
break;
case 1:
gtk_window_set_title (GTK_WINDOW (window), "Scrolling plain text");
populate_text (FALSE);
break;
case 2:
gtk_window_set_title (GTK_WINDOW (window), "Scrolling complex text");
populate_text (TRUE);
break;
default:
g_assert_not_reached ();
}
tick_cb = gtk_widget_add_tick_callback (window, scroll_cb, NULL, NULL);
}
static void
next_clicked_cb (GtkButton *source,
gpointer user_data)
{
int new_index;
if (selected + 1 >= N_WIDGET_TYPES)
new_index = 0;
else
new_index = selected + 1;
set_widget_type (new_index);
}
static void
prev_clicked_cb (GtkButton *source,
gpointer user_data)
{
int new_index;
if (selected - 1 < 0)
new_index = N_WIDGET_TYPES - 1;
else
new_index = selected - 1;
set_widget_type (new_index);
}
GtkWidget *
do_iconscroll (GtkWidget *do_widget)
{
if (!window)
{
GtkBuilder *builder;
builder = gtk_builder_new_from_resource ("/iconscroll/iconscroll.ui");
gtk_builder_add_callback_symbols (builder,
"next_clicked_cb", G_CALLBACK (next_clicked_cb),
"prev_clicked_cb", G_CALLBACK (prev_clicked_cb),
NULL);
gtk_builder_connect_signals (builder, NULL);
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed), &window);
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed), &window);
scrolledwindow = GTK_WIDGET (gtk_builder_get_object (builder, "scrolledwindow"));
gtk_widget_realize (window);
adjustment = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "adjustment"));
set_widget_type (0);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_widget_destroy (window);
return window;
}

View File

@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow" id="window">
<property name="resizable">0</property>
<property name="default-width">500</property>
<property name="default-height">500</property>
<child type="titlebar">
<object class="GtkHeaderBar">
<property name="show-title-buttons">1</property>
<child>
<object class="GtkBox">
<style>
<class name="linked"/>
</style>
<child>
<object class="GtkButton">
<property name="icon-name">pan-start-symbolic</property>
<signal name="clicked" handler="prev_clicked_cb"/>
</object>
</child>
<child>
<object class="GtkButton">
<property name="icon-name">pan-end-symbolic</property>
<signal name="clicked" handler="next_clicked_cb"/>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow">
<property name="hscrollbar-policy">never</property>
<property name="vscrollbar-policy">automatic</property>
<property name="vadjustment"><object class="GtkAdjustment" id="adjustment"/></property>
</object>
</child>
</object>
</interface>

View File

@@ -68,7 +68,7 @@ do_infobar (GtkWidget *do_widget)
gtk_container_add (GTK_CONTAINER (vbox), bar);
gtk_info_bar_set_message_type (GTK_INFO_BAR (bar), GTK_MESSAGE_INFO);
label = gtk_label_new ("This is an info bar with message type GTK_MESSAGE_INFO");
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
gtk_label_set_wrap (GTK_LABEL (label), TRUE);
gtk_label_set_xalign (GTK_LABEL (label), 0);
gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_content_area (GTK_INFO_BAR (bar))), label);
@@ -80,7 +80,7 @@ do_infobar (GtkWidget *do_widget)
gtk_container_add (GTK_CONTAINER (vbox), bar);
gtk_info_bar_set_message_type (GTK_INFO_BAR (bar), GTK_MESSAGE_WARNING);
label = gtk_label_new ("This is an info bar with message type GTK_MESSAGE_WARNING");
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
gtk_label_set_wrap (GTK_LABEL (label), TRUE);
gtk_label_set_xalign (GTK_LABEL (label), 0);
gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_content_area (GTK_INFO_BAR (bar))), label);
@@ -94,7 +94,7 @@ do_infobar (GtkWidget *do_widget)
gtk_container_add (GTK_CONTAINER (vbox), bar);
gtk_info_bar_set_message_type (GTK_INFO_BAR (bar), GTK_MESSAGE_QUESTION);
label = gtk_label_new ("This is an info bar with message type GTK_MESSAGE_QUESTION");
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
gtk_label_set_wrap (GTK_LABEL (label), TRUE);
gtk_label_set_xalign (GTK_LABEL (label), 0);
gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_content_area (GTK_INFO_BAR (bar))), label);
@@ -106,7 +106,7 @@ do_infobar (GtkWidget *do_widget)
gtk_container_add (GTK_CONTAINER (vbox), bar);
gtk_info_bar_set_message_type (GTK_INFO_BAR (bar), GTK_MESSAGE_ERROR);
label = gtk_label_new ("This is an info bar with message type GTK_MESSAGE_ERROR");
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
gtk_label_set_wrap (GTK_LABEL (label), TRUE);
gtk_label_set_xalign (GTK_LABEL (label), 0);
gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_content_area (GTK_INFO_BAR (bar))), label);
@@ -119,7 +119,7 @@ do_infobar (GtkWidget *do_widget)
gtk_container_add (GTK_CONTAINER (vbox), bar);
gtk_info_bar_set_message_type (GTK_INFO_BAR (bar), GTK_MESSAGE_OTHER);
label = gtk_label_new ("This is an info bar with message type GTK_MESSAGE_OTHER");
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
gtk_label_set_wrap (GTK_LABEL (label), TRUE);
gtk_label_set_xalign (GTK_LABEL (label), 0);
gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_content_area (GTK_INFO_BAR (bar))), label);

View File

@@ -202,7 +202,7 @@ languages_variant_init (const char *variant)
else
g_warning ("Failed to load '%s': %s\n", filename, error->message);
g_free (error);
g_clear_error (&error);
g_free (filename);
g_free (buf);
}

View File

@@ -8,6 +8,7 @@
#include <gtk/gtk.h>
#include <stdlib.h>
#include <string.h>
#include "award.h"
static GdkPixbuf *avatar_pixbuf_other;
static GtkWidget *window = NULL;
@@ -234,9 +235,9 @@ reshare_clicked (GtkMessageRow *row,
{
GtkMessageRowPrivate *priv = row->priv;
award ("listbox-reshare");
priv->message->n_reshares++;
gtk_message_row_update (row);
}
static void
@@ -255,11 +256,14 @@ gtk_message_row_state_flags_changed (GtkWidget *widget,
{
GtkMessageRowPrivate *priv = GTK_MESSAGE_ROW (widget)->priv;
GtkStateFlags flags;
gboolean visible;
flags = gtk_widget_get_state_flags (widget);
gtk_widget_set_visible (priv->extra_buttons_box,
flags & (GTK_STATE_FLAG_PRELIGHT | GTK_STATE_FLAG_SELECTED));
visible = flags & (GTK_STATE_FLAG_PRELIGHT | GTK_STATE_FLAG_SELECTED) ? TRUE : FALSE;
gtk_widget_set_visible (priv->extra_buttons_box, visible);
if (visible && gtk_list_box_row_get_index (GTK_LIST_BOX_ROW (widget)) % 100 == 99)
award ("listbox-100th-row");
GTK_WIDGET_CLASS (gtk_message_row_parent_class)->state_flags_changed (widget, previous_state_flags);
}

View File

@@ -0,0 +1,210 @@
/* Lists/File browser
*
* This demo shows off the different layouts that are quickly achievable
* with GtkGridView by implementing a file browser with different views.
*/
#include <glib/gi18n.h>
#include <gtk/gtk.h>
static GtkWidget *window = NULL;
/* Create a simple object that holds the data for the different views */
typedef struct _FileBrowserView FileBrowserView;
struct _FileBrowserView
{
GObject parent_instance;
GtkListItemFactory *factory;
char *icon_name;
GtkOrientation orientation;
};
enum {
PROP_0,
PROP_FACTORY,
PROP_ICON_NAME,
PROP_ORIENTATION,
N_PROPS
};
#define FILE_BROWSER_TYPE_VIEW (file_browser_view_get_type ())
G_DECLARE_FINAL_TYPE (FileBrowserView, file_browser_view, FILE_BROWSER, VIEW, GObject);
G_DEFINE_TYPE (FileBrowserView, file_browser_view, G_TYPE_OBJECT);
static GParamSpec *properties[N_PROPS] = { NULL, };
static void
file_browser_view_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
FileBrowserView *self = FILE_BROWSER_VIEW (object);
switch (property_id)
{
case PROP_FACTORY:
g_value_set_object (value, self->factory);
break;
case PROP_ICON_NAME:
g_value_set_string (value, self->icon_name);
break;
case PROP_ORIENTATION:
g_value_set_enum (value, self->orientation);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
file_browser_view_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
FileBrowserView *self = FILE_BROWSER_VIEW (object);
switch (prop_id)
{
case PROP_FACTORY:
g_set_object (&self->factory, g_value_get_object (value));
break;
case PROP_ICON_NAME:
g_free (self->icon_name);
self->icon_name = g_value_dup_string (value);
break;
case PROP_ORIENTATION:
self->orientation = g_value_get_enum (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
file_browser_view_finalize (GObject *object)
{
FileBrowserView *self = FILE_BROWSER_VIEW (object);
g_object_unref (self->factory);
g_free (self->icon_name);
G_OBJECT_CLASS (file_browser_view_parent_class)->dispose (object);
}
static void
file_browser_view_class_init (FileBrowserViewClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->get_property = file_browser_view_get_property;
gobject_class->set_property = file_browser_view_set_property;
gobject_class->finalize = file_browser_view_finalize;
properties[PROP_FACTORY] =
g_param_spec_object ("factory",
"factory",
"factory to use in the main view",
GTK_TYPE_LIST_ITEM_FACTORY,
G_PARAM_READWRITE);
properties[PROP_ICON_NAME] =
g_param_spec_string ("icon-name",
"icon name",
"icon to display for selecting this view",
NULL,
G_PARAM_READWRITE);
properties[PROP_ORIENTATION] =
g_param_spec_enum ("orientation",
"orientation",
"orientation of the view",
GTK_TYPE_ORIENTATION,
GTK_ORIENTATION_VERTICAL,
G_PARAM_READWRITE);
g_object_class_install_properties (gobject_class, N_PROPS, properties);
}
static void file_browser_view_init (FileBrowserView *self)
{
}
static void
up_clicked_cb (GtkButton *button,
GtkDirectoryList *list)
{
GFile *file;
file = g_file_get_parent (gtk_directory_list_get_file (list));
if (file == NULL)
return;
gtk_directory_list_set_file (list, file);
}
static void
view_activated_cb (GtkGridView *view,
guint pos,
GtkDirectoryList *list)
{
GFileInfo *info;
info = g_list_model_get_item (gtk_grid_view_get_model (view), pos);
if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY)
gtk_directory_list_set_file (list, G_FILE (g_file_info_get_attribute_object (info, "standard::file")));
g_object_unref (info);
}
GtkWidget *
do_listview_filebrowser (GtkWidget *do_widget)
{
if (!window)
{
GtkWidget *view;
GtkBuilder *builder;
GtkDirectoryList *dirlist;
GFile *file;
builder = gtk_builder_new_from_resource ("/listview_filebrowser/listview_filebrowser.ui");
gtk_builder_add_callback_symbols (builder,
"up_clicked_cb", G_CALLBACK (up_clicked_cb),
"view_activated_cb", G_CALLBACK (view_activated_cb),
NULL);
gtk_builder_connect_signals (builder, NULL);
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed), &window);
/* Create the model and fill it with the contents of the current directory */
file = g_file_new_for_path (g_get_current_dir ());
dirlist = GTK_DIRECTORY_LIST (gtk_builder_get_object (builder, "dirlist"));
gtk_directory_list_set_file (dirlist, file);
g_object_unref (file);
/* grab focus in the view */
view = GTK_WIDGET (gtk_builder_get_object (builder, "view"));
gtk_widget_grab_focus (view);
g_object_unref (builder);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_widget_destroy (window);
return window;
}

View File

@@ -0,0 +1,196 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GListStore" id="viewlist">
<property name="item-type">FileBrowserView</property>
<child>
<object class="FileBrowserView">
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="bytes"><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<child>
<object class="GtkBox">
<child>
<object class="GtkImage">
<binding name="gicon">file-info(GtkListItem.item:GFileInfo, "standard::icon", object):GIcon</binding>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="halign">start</property>
<binding name="label">file-info(GtkListItem.item:GFileInfo, "standard::display-name", string)</binding>
</object>
</child>
</object>
</child>
</template>
</interface>
]]></property>
</object>
</property>
<property name="icon-name">view-list-symbolic</property>
<property name="orientation">horizontal</property>
</object>
</child>
<child>
<object class="FileBrowserView">
<property name="icon-name">view-grid-symbolic</property>
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="bytes"><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="GtkImage">
<property name="icon-size">large</property>
<binding name="gicon">file-info(GtkListItem.item:GFileInfo, "standard::icon", object):GIcon</binding>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="wrap">1</property>
<property name="wrap-mode">word-char</property>
<property name="lines">2</property>
<property name="ellipsize">end</property>
<property name="width-chars">10</property>
<property name="max-width-chars">30</property>
<binding name="label">file-info(GtkListItem.item:GFileInfo, "standard::display-name", string)</binding>
</object>
</child>
</object>
</child>
</template>
</interface>
]]></property>
</object>
</property>
<property name="orientation">vertical</property>
</object>
</child>
<child>
<object class="FileBrowserView">
<property name="icon-name">view-paged-symbolic</property>
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="bytes"><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<child>
<object class="GtkBox">
<child>
<object class="GtkImage">
<property name="icon-size">large</property>
<binding name="gicon">file-info(GtkListItem.item:GFileInfo, "standard::icon", object):GIcon</binding>
</object>
</child>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel">
<property name="halign">start</property>
<binding name="label">file-info(GtkListItem.item:GFileInfo, "standard::display-name", string)</binding>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="halign">start</property>
<binding name="label">file-info(GtkListItem.item:GFileInfo, "standard::size", uint64) + " bytes"</binding>
<style>
<class name="dim-label"/>
</style>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="halign">start</property>
<binding name="label">file-info(GtkListItem.item:GFileInfo, "standard::content-type", string)</binding>
<style>
<class name="dim-label"/>
</style>
</object>
</child>
</object>
</child>
</object>
</child>
</template>
</interface>
]]></property>
</object>
</property>
<property name="orientation">horizontal</property>
</object>
</child>
</object>
<object class="GtkDirectoryList" id="dirlist">
<property name="attributes">standard::name,standard::display-name,standard::icon,standard::size,standard::content-type</property>
</object>
<object class="GtkWindow" id="window">
<property name="title" translatable="yes">File browser</property>
<property name="default-width">600</property>
<property name="default-height">400</property>
<child type="titlebar">
<object class="GtkHeaderBar" id="">
<property name="show-title-buttons">1</property>
<child>
<object class="GtkButton">
<property name="icon-name">go-up</property>
<signal name="clicked" handler="up_clicked_cb" object="dirlist" swapped="no"/>
</object>
</child>
<child type="end">
<object class="GtkListView">
<property name="valign">center</property>
<property name="orientation">horizontal</property>
<style>
<class name="linked"/>
</style>
<property name="model">
<object class="GtkSingleSelection" id="selected-view">
<property name="model">viewlist</property>
</object>
</property>
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="bytes"><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<child>
<object class="GtkImage">
<binding name="icon-name">GtkListItem.item:FileBrowserView.icon-name</binding>
</object>
</child>
</template>
</interface>
]]></property>
</object>
</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkScrolledWindow">
<property name="can-focus">1</property>
<child>
<object class="GtkGridView" id="view">
<property name="model">dirlist</property>
<property name="max-columns">15</property>
<binding name="factory">selected-view.selected-item:FileBrowserView.factory</binding>
<binding name="orientation">selected-view.selected-item:FileBrowserView.orientation</binding>
<signal name="activate" handler="view_activated_cb" object="dirlist" swapped="no"/>
</object>
</child>
</object>
</child>
</object>
</interface>

View File

@@ -0,0 +1,478 @@
/* Lists/Minesweeper
*
* This demo shows how to develop a user interface for small game using a
* gridview.
*
* It demonstrates how to use the activate signal and single-press behavior
* to implement rather different interaction behavior to a typical list.
*/
#include <glib/gi18n.h>
#include <gtk/gtk.h>
/*** The cell object ***/
/* Create an object that holds the data for a cell in the game */
typedef struct _SweeperCell SweeperCell;
struct _SweeperCell
{
GObject parent_instance;
gboolean is_mine;
gboolean is_visible;
guint neighbor_mines;
};
enum {
CELL_PROP_0,
CELL_PROP_LABEL,
N_CELL_PROPS
};
#define SWEEPER_TYPE_CELL (sweeper_cell_get_type ())
G_DECLARE_FINAL_TYPE (SweeperCell, sweeper_cell, SWEEPER, CELL, GObject);
G_DEFINE_TYPE (SweeperCell, sweeper_cell, G_TYPE_OBJECT);
static GParamSpec *cell_properties[N_CELL_PROPS] = { NULL, };
static const char *
sweeper_cell_get_label (SweeperCell *self)
{
static const char *minecount_labels[10] = { "", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
if (!self->is_visible)
return "?";
if (self->is_mine)
return "💣";
return minecount_labels[self->neighbor_mines];
}
static void
sweeper_cell_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
SweeperCell *self = SWEEPER_CELL (object);
switch (property_id)
{
case CELL_PROP_LABEL:
g_value_set_string (value, sweeper_cell_get_label (self));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
sweeper_cell_class_init (SweeperCellClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->get_property = sweeper_cell_get_property;
cell_properties[CELL_PROP_LABEL] =
g_param_spec_string ("label",
"label",
"label to display for this row",
NULL,
G_PARAM_READABLE);
g_object_class_install_properties (gobject_class, N_CELL_PROPS, cell_properties);
}
static void
sweeper_cell_init (SweeperCell *self)
{
}
static void
sweeper_cell_reveal (SweeperCell *self)
{
if (self->is_visible)
return;
self->is_visible = TRUE;
g_object_notify_by_pspec (G_OBJECT (self), cell_properties[CELL_PROP_LABEL]);
}
static SweeperCell *
sweeper_cell_new ()
{
return g_object_new (SWEEPER_TYPE_CELL, NULL);
}
/*** The board object ***/
/* Create an object that holds the data for the game */
typedef struct _SweeperGame SweeperGame;
struct _SweeperGame
{
GObject parent_instance;
GPtrArray *cells;
guint width;
guint height;
gboolean playing;
gboolean win;
};
enum {
GAME_PROP_0,
GAME_PROP_HEIGHT,
GAME_PROP_PLAYING,
GAME_PROP_WIDTH,
GAME_PROP_WIN,
N_GAME_PROPS
};
#define SWEEPER_TYPE_GAME (sweeper_game_get_type ())
G_DECLARE_FINAL_TYPE (SweeperGame, sweeper_game, SWEEPER, GAME, GObject);
static GType
sweeper_game_list_model_get_item_type (GListModel *model)
{
return SWEEPER_TYPE_GAME;
}
static guint
sweeper_game_list_model_get_n_items (GListModel *model)
{
SweeperGame *self = SWEEPER_GAME (model);
return self->width * self->height;
}
static gpointer
sweeper_game_list_model_get_item (GListModel *model,
guint position)
{
SweeperGame *self = SWEEPER_GAME (model);
return g_object_ref (g_ptr_array_index (self->cells, position));
}
static void
sweeper_game_list_model_init (GListModelInterface *iface)
{
iface->get_item_type = sweeper_game_list_model_get_item_type;
iface->get_n_items = sweeper_game_list_model_get_n_items;
iface->get_item = sweeper_game_list_model_get_item;
}
G_DEFINE_TYPE_WITH_CODE (SweeperGame, sweeper_game, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, sweeper_game_list_model_init))
static GParamSpec *game_properties[N_GAME_PROPS] = { NULL, };
static void
sweeper_game_dispose (GObject *object)
{
SweeperGame *self = SWEEPER_GAME (object);
g_clear_pointer (&self->cells, g_ptr_array_unref);
G_OBJECT_CLASS (sweeper_game_parent_class)->dispose (object);
}
static void
sweeper_game_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
SweeperGame *self = SWEEPER_GAME (object);
switch (property_id)
{
case GAME_PROP_HEIGHT:
g_value_set_uint (value, self->height);
break;
case GAME_PROP_PLAYING:
g_value_set_boolean (value, self->playing);
break;
case GAME_PROP_WIDTH:
g_value_set_uint (value, self->width);
break;
case GAME_PROP_WIN:
g_value_set_boolean (value, self->win);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
sweeper_game_class_init (SweeperGameClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->dispose = sweeper_game_dispose;
gobject_class->get_property = sweeper_game_get_property;
game_properties[GAME_PROP_HEIGHT] =
g_param_spec_uint ("height",
"height",
"height of the game grid",
1, G_MAXUINT, 8,
G_PARAM_READABLE);
game_properties[GAME_PROP_PLAYING] =
g_param_spec_boolean ("playing",
"playing",
"if the game is still going on",
FALSE,
G_PARAM_READABLE);
game_properties[GAME_PROP_WIDTH] =
g_param_spec_uint ("width",
"width",
"width of the game grid",
1, G_MAXUINT, 8,
G_PARAM_READABLE);
game_properties[GAME_PROP_WIN] =
g_param_spec_boolean ("win",
"win",
"if the game was won",
FALSE,
G_PARAM_READABLE);
g_object_class_install_properties (gobject_class, N_GAME_PROPS, game_properties);
}
static void
sweeper_game_reset_board (SweeperGame *self,
guint width,
guint height)
{
guint i;
g_ptr_array_set_size (self->cells, 0);
for (i = 0; i < width * height; i++)
{
g_ptr_array_add (self->cells, sweeper_cell_new ());
}
if (self->width != width)
{
self->width = width;
g_object_notify_by_pspec (G_OBJECT (self), game_properties[GAME_PROP_WIDTH]);
}
if (self->height != height)
{
self->height = height;
g_object_notify_by_pspec (G_OBJECT (self), game_properties[GAME_PROP_HEIGHT]);
}
if (!self->playing)
{
self->playing = TRUE;
g_object_notify_by_pspec (G_OBJECT (self), game_properties[GAME_PROP_PLAYING]);
}
if (self->win)
{
self->win = FALSE;
g_object_notify_by_pspec (G_OBJECT (self), game_properties[GAME_PROP_WIN]);
}
}
static void
sweeper_game_place_mines (SweeperGame *self,
guint n_mines)
{
guint i;
for (i = 0; i < n_mines; i++)
{
SweeperCell *cell;
do {
cell = g_ptr_array_index (self->cells, g_random_int_range (0, self->cells->len));
} while (cell->is_mine);
cell->is_mine = TRUE;
}
}
static SweeperCell *
get_cell (SweeperGame *self,
guint x,
guint y)
{
return g_ptr_array_index (self->cells, y * self->width + x);
}
static void
sweeper_game_count_neighbor_mines (SweeperGame *self,
guint width,
guint height)
{
guint x, y, x2, y2;
for (y = 0; y < height; y++)
{
for (x = 0; x < width; x++)
{
SweeperCell *cell = get_cell (self, x, y);
for (y2 = MAX (1, y) - 1; y2 < MIN (height, y + 2); y2++)
{
for (x2 = MAX (1, x) - 1; x2 < MIN (width, x + 2); x2++)
{
SweeperCell *other = get_cell (self, x2, y2);
if (other->is_mine)
cell->neighbor_mines++;
}
}
}
}
}
static void
sweeper_game_new_game (SweeperGame *self,
guint width,
guint height,
guint n_mines)
{
guint n_items_before;
g_return_if_fail (n_mines <= width * height);
n_items_before = self->width * self->height;
g_object_freeze_notify (G_OBJECT (self));
sweeper_game_reset_board (self, width, height);
sweeper_game_place_mines (self, n_mines);
sweeper_game_count_neighbor_mines (self, width, height);
g_list_model_items_changed (G_LIST_MODEL (self), 0, n_items_before, width * height);
g_object_thaw_notify (G_OBJECT (self));
}
static void
sweeper_game_init (SweeperGame *self)
{
self->cells = g_ptr_array_new_with_free_func (g_object_unref);
sweeper_game_new_game (self, 8, 8, 10);
}
static void
sweeper_game_end (SweeperGame *self,
gboolean win)
{
if (self->playing)
{
self->playing = FALSE;
g_object_notify_by_pspec (G_OBJECT (self), game_properties[GAME_PROP_PLAYING]);
}
if (self->win != win)
{
self->win = win;
g_object_notify_by_pspec (G_OBJECT (self), game_properties[GAME_PROP_WIN]);
}
}
static void
sweeper_game_check_finished (SweeperGame *self)
{
guint i;
if (!self->playing)
return;
for (i = 0; i < self->cells->len; i++)
{
SweeperCell *cell = g_ptr_array_index (self->cells, i);
/* There's still a non-revealed cell that isn't a mine */
if (!cell->is_visible && !cell->is_mine)
return;
}
sweeper_game_end (self, TRUE);
}
static void
sweeper_game_reveal_cell (SweeperGame *self,
guint position)
{
SweeperCell *cell;
if (!self->playing)
return;
cell = g_ptr_array_index (self->cells, position);
sweeper_cell_reveal (cell);
if (cell->is_mine)
sweeper_game_end (self, FALSE);
sweeper_game_check_finished (self);
}
static void
cell_clicked_cb (GtkGridView *gridview,
guint pos,
SweeperGame *game)
{
sweeper_game_reveal_cell (game, pos);
}
static void
new_game_cb (GtkButton *button,
SweeperGame *game)
{
sweeper_game_new_game (game, 8, 8, 10);
}
static GtkWidget *window = NULL;
GtkWidget *
do_listview_minesweeper (GtkWidget *do_widget)
{
if (window == NULL)
{
GtkBuilder *builder;
g_type_ensure (SWEEPER_TYPE_GAME);
builder = gtk_builder_new_from_resource ("/listview_minesweeper/listview_minesweeper.ui");
gtk_builder_add_callback_symbols (builder,
"cell_clicked_cb", G_CALLBACK (cell_clicked_cb),
"new_game_cb", G_CALLBACK (new_game_cb),
NULL);
gtk_builder_connect_signals (builder, NULL);
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed), &window);
g_object_unref (builder);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_widget_destroy (window);
return window;
}

View File

@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="SweeperGame" id="game">
</object>
<object class="GtkWindow" id="window">
<property name="title" translatable="yes">Minesweeper</property>
<child type="titlebar">
<object class="GtkHeaderBar" id="">
<property name="show-title-buttons">1</property>
<child>
<object class="GtkButton">
<property name="label">New Game</property>
<signal name="clicked" handler="new_game_cb" object="game" swapped="no"/>
</object>
</child>
<child type="title">
<object class="GtkImage">
<property name="icon-name">trophy-gold</property>
<binding name="visible">game.win</binding>
</object>
</child>
</object>
</child>
<child>
<object class="GtkGridView" id="view">
<property name="model">
<object class="GtkNoSelection">
<property name="model">game</property>
</object>
</property>
<binding name="max-columns">game.width</binding>
<binding name="min-columns">game.width</binding>
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="resource">/listview_minesweeper/listview_minesweeper_cell.ui</property>
</object>
</property>
<signal name="activate" handler="cell_clicked_cb" object="game" swapped="no"/>
</object>
</child>
</object>
</interface>

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<child>
<object class="GtkLabel">
<property name="halign">center</property>
<property name="valign">center</property>
<binding name="label">GtkListItem.item:SweeperCell.label</binding>
</object>
</child>
</template>
</interface>

View File

@@ -0,0 +1,147 @@
/* Lists/Settings
*
* This demo shows a settings viwer for GSettings.
*
* It demonstrates how to implement support for trees with listview.
*/
#include <gtk/gtk.h>
static int
strvcmp (gconstpointer p1,
gconstpointer p2)
{
const char * const *s1 = p1;
const char * const *s2 = p2;
return strcmp (*s1, *s2);
}
static GListModel *
create_settings_model (gpointer item,
gpointer unused)
{
GSettings *settings = item;
char **schemas;
GListStore *result;
guint i;
if (settings == NULL)
{
g_settings_schema_source_list_schemas (g_settings_schema_source_get_default (),
TRUE,
&schemas,
NULL);
}
else
{
schemas = g_settings_list_children (settings);
}
if (schemas == NULL || schemas[0] == NULL)
{
g_free (schemas);
return NULL;
}
qsort (schemas, g_strv_length (schemas), sizeof (char *), strvcmp);
result = g_list_store_new (G_TYPE_SETTINGS);
for (i = 0; schemas[i] != NULL; i++)
{
GSettings *child;
if (settings == NULL)
child = g_settings_new (schemas[i]);
else
child = g_settings_get_child (settings, schemas[i]);
g_list_store_append (result, child);
g_object_unref (child);
}
return G_LIST_MODEL (result);
}
static void
setup_widget (GtkListItem *list_item,
gpointer unused)
{
GtkWidget *label, *expander;
expander = gtk_tree_expander_new ();
gtk_container_add (GTK_CONTAINER (list_item), expander);
label = gtk_label_new (NULL);
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
gtk_tree_expander_set_child (GTK_TREE_EXPANDER (expander), label);
}
static void
bind_widget (GtkListItem *list_item,
gpointer unused)
{
GSettings *settings;
GtkWidget *label, *expander;
GSettingsSchema *schema;
expander = gtk_bin_get_child (GTK_BIN (list_item));
gtk_tree_expander_set_list_row (GTK_TREE_EXPANDER (expander), gtk_list_item_get_item (list_item));
label = gtk_tree_expander_get_child (GTK_TREE_EXPANDER (expander));
settings = gtk_tree_expander_get_item (GTK_TREE_EXPANDER (expander));
g_object_get (settings, "settings-schema", &schema, NULL);
gtk_label_set_label (GTK_LABEL (label), g_settings_schema_get_id (schema));
g_settings_schema_unref (schema);
}
static GtkWidget *window = NULL;
GtkWidget *
do_listview_settings (GtkWidget *do_widget)
{
if (window == NULL)
{
GtkWidget *listview, *sw;;
GListModel *model;
GtkTreeListModel *treemodel;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_default_size (GTK_WINDOW (window), 400, 600);
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Settings");
g_signal_connect (window, "destroy",
G_CALLBACK(gtk_widget_destroyed), &window);
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_container_add (GTK_CONTAINER (window), sw);
listview = gtk_list_view_new_with_factory (
gtk_functions_list_item_factory_new (setup_widget,
bind_widget,
NULL, NULL));
model = create_settings_model (NULL, NULL);
treemodel = gtk_tree_list_model_new (FALSE,
model,
TRUE,
create_settings_model,
NULL,
NULL);
gtk_list_view_set_model (GTK_LIST_VIEW (listview), G_LIST_MODEL (treemodel));
g_object_unref (treemodel);
g_object_unref (model);
gtk_container_add (GTK_CONTAINER (sw), listview);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_widget_destroy (window);
return window;
}

View File

@@ -0,0 +1,316 @@
/* Lists/Weather
*
* This demo shows a few of the rarer features of GtkListView and
* how they can be used to display weather information.
*
* The hourly weather info uses a horizontal listview. This is easy
* to achieve because GtkListView implements the GtkOrientable interface.
*
* To make the items in the list stand out more, the listview uses
* separators.
*
* A GtkNoSelectionModel is used to make sure no item in the list can be
* selected. All other interactions with the items is still possible.
*/
#include <gtk/gtk.h>
#define GTK_TYPE_WEATHER_INFO (gtk_weather_info_get_type ())
G_DECLARE_FINAL_TYPE (GtkWeatherInfo, gtk_weather_info, GTK, WEATHER_INFO, GObject)
typedef enum {
GTK_WEATHER_CLEAR,
GTK_WEATHER_FEW_CLOUDS,
GTK_WEATHER_FOG,
GTK_WEATHER_OVERCAST,
GTK_WEATHER_SCATTERED_SHOWERS,
GTK_WEATHER_SHOWERS,
GTK_WEATHER_SNOW,
GTK_WEATHER_STORM
} GtkWeatherType;
struct _GtkWeatherInfo
{
GObject parent_instance;
gint64 timestamp;
int temperature;
GtkWeatherType weather_type;
};
struct _GtkWeatherInfoClass
{
GObjectClass parent_class;
};
static void
gtk_weather_info_class_init (GtkWeatherInfoClass *klass)
{
}
static void
gtk_weather_info_init (GtkWeatherInfo *self)
{
}
G_DEFINE_TYPE (GtkWeatherInfo, gtk_weather_info, G_TYPE_OBJECT);
static GtkWeatherInfo *
gtk_weather_info_new (GDateTime *timestamp,
GtkWeatherInfo *copy_from)
{
GtkWeatherInfo *result;
result = g_object_new (GTK_TYPE_WEATHER_INFO, NULL);
result->timestamp = g_date_time_to_unix (timestamp);
if (copy_from)
{
result->temperature = copy_from->temperature;
result->weather_type = copy_from->weather_type;
g_object_unref (copy_from);
}
return result;
}
static GDateTime *
parse_timestamp (const char *string,
GTimeZone *timezone)
{
char *with_seconds;
GDateTime *result;
with_seconds = g_strconcat (string, ":00", NULL);
result = g_date_time_new_from_iso8601 (with_seconds, timezone);
g_free (with_seconds);
return result;
}
static GtkWeatherType
parse_weather_type (const char *clouds,
const char *precip,
GtkWeatherType fallback)
{
if (strstr (precip, "SN"))
return GTK_WEATHER_SNOW;
if (strstr (precip, "TS"))
return GTK_WEATHER_STORM;
if (strstr (precip, "DZ"))
return GTK_WEATHER_SCATTERED_SHOWERS;
if (strstr (precip, "SH") || strstr (precip, "RA"))
return GTK_WEATHER_SHOWERS;
if (strstr (precip, "FG"))
return GTK_WEATHER_FOG;
if (g_str_equal (clouds, "M") ||
g_str_equal (clouds, ""))
return fallback;
if (strstr (clouds, "OVC") ||
strstr (clouds, "BKN"))
return GTK_WEATHER_OVERCAST;
if (strstr (clouds, "BKN") ||
strstr (clouds, "SCT"))
return GTK_WEATHER_FEW_CLOUDS;
if (strstr (clouds, "VV"))
return GTK_WEATHER_FOG;
return GTK_WEATHER_CLEAR;
}
static double
parse_temperature (const char *s,
double fallback)
{
char *endptr;
double d;
d = g_ascii_strtod (s, &endptr);
if (*endptr != '\0')
return fallback;
return d;
}
static GListModel *
create_weather_model (void)
{
GListStore *store;
GTimeZone *utc;
GDateTime *timestamp;
GtkWeatherInfo *info;
GBytes *data;
char **lines;
guint i;
store = g_list_store_new (GTK_TYPE_WEATHER_INFO);
data = g_resources_lookup_data ("/listview_weather/listview_weather.txt", 0, NULL);
lines = g_strsplit (g_bytes_get_data (data, NULL), "\n", 0);
utc = g_time_zone_new_utc ();
timestamp = g_date_time_new (utc, 2011, 1, 1, 0, 0, 0);
info = gtk_weather_info_new (timestamp, NULL);
g_list_store_append (store, info);
for (i = 0; lines[i] != NULL && *lines[i]; i++)
{
char **fields;
GDateTime *date;
fields = g_strsplit (lines[i], ",", 0);
date = parse_timestamp (fields[0], utc);
while (g_date_time_difference (date, timestamp) > 30 * G_TIME_SPAN_MINUTE)
{
GDateTime *new_timestamp = g_date_time_add_hours (timestamp, 1);
g_date_time_unref (timestamp);
timestamp = new_timestamp;
info = gtk_weather_info_new (timestamp, info);
g_list_store_append (store, info);
}
info->temperature = parse_temperature (fields[1], info->temperature);
info->weather_type = parse_weather_type (fields[2], fields[3], info->weather_type);
g_date_time_unref (date);
g_strfreev (fields);
}
g_strfreev (lines);
g_bytes_unref (data);
g_time_zone_unref (utc);
return G_LIST_MODEL (store);
}
static void
setup_widget (GtkListItem *list_item,
gpointer unused)
{
GtkWidget *box, *child;
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_container_add (GTK_CONTAINER (list_item), box);
child = gtk_label_new (NULL);
gtk_label_set_width_chars (GTK_LABEL (child), 5);
gtk_container_add (GTK_CONTAINER (box), child);
child = gtk_image_new ();
gtk_image_set_icon_size (GTK_IMAGE (child), GTK_ICON_SIZE_LARGE);
gtk_container_add (GTK_CONTAINER (box), child);
child = gtk_label_new (NULL);
gtk_widget_set_vexpand (child, TRUE);
gtk_widget_set_valign (child, GTK_ALIGN_END);
gtk_label_set_width_chars (GTK_LABEL (child), 4);
gtk_container_add (GTK_CONTAINER (box), child);
}
static void
bind_widget (GtkListItem *list_item,
gpointer unused)
{
GtkWidget *box, *child;
GtkWeatherInfo *info;
GDateTime *timestamp;
char *s;
box = gtk_bin_get_child (GTK_BIN (list_item));
info = gtk_list_item_get_item (list_item);
child = gtk_widget_get_first_child (box);
timestamp = g_date_time_new_from_unix_utc (info->timestamp);
s = g_date_time_format (timestamp, "%R");
gtk_label_set_text (GTK_LABEL (child), s);
g_free (s);
g_date_time_unref (timestamp);
child = gtk_widget_get_next_sibling (child);
switch (info->weather_type)
{
case GTK_WEATHER_CLEAR:
gtk_image_set_from_icon_name (GTK_IMAGE (child), "weather-clear-symbolic");
break;
case GTK_WEATHER_FEW_CLOUDS:
gtk_image_set_from_icon_name (GTK_IMAGE (child), "weather-few-clouds-symbolic");
break;
case GTK_WEATHER_FOG:
gtk_image_set_from_icon_name (GTK_IMAGE (child), "weather-fog-symbolic");
break;
case GTK_WEATHER_OVERCAST:
gtk_image_set_from_icon_name (GTK_IMAGE (child), "weather-overcast-symbolic");
break;
case GTK_WEATHER_SCATTERED_SHOWERS:
gtk_image_set_from_icon_name (GTK_IMAGE (child), "weather-showers-scattered-symbolic");
break;
case GTK_WEATHER_SHOWERS:
gtk_image_set_from_icon_name (GTK_IMAGE (child), "weather-showers-symbolic");
break;
case GTK_WEATHER_SNOW:
gtk_image_set_from_icon_name (GTK_IMAGE (child), "weather-snow-symbolic");
break;
case GTK_WEATHER_STORM:
gtk_image_set_from_icon_name (GTK_IMAGE (child), "weather-storm-symbolic");
break;
default:
gtk_image_clear (GTK_IMAGE (child));
break;
}
child = gtk_widget_get_next_sibling (child);
s = g_strdup_printf ("%d°", info->temperature);
gtk_label_set_text (GTK_LABEL (child), s);
g_free (s);
}
static GtkWidget *window = NULL;
GtkWidget *
do_listview_weather (GtkWidget *do_widget)
{
if (window == NULL)
{
GtkWidget *listview, *sw;;
GListModel *model, *selection;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Weather");
g_signal_connect (window, "destroy",
G_CALLBACK(gtk_widget_destroyed), &window);
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_container_add (GTK_CONTAINER (window), sw);
listview = gtk_list_view_new_with_factory (
gtk_functions_list_item_factory_new (setup_widget,
bind_widget,
NULL, NULL));
gtk_orientable_set_orientation (GTK_ORIENTABLE (listview), GTK_ORIENTATION_HORIZONTAL);
gtk_list_view_set_show_separators (GTK_LIST_VIEW (listview), TRUE);
model = create_weather_model ();
selection = G_LIST_MODEL (gtk_no_selection_new (model));
gtk_list_view_set_model (GTK_LIST_VIEW (listview), selection);
g_object_unref (selection);
g_object_unref (model);
gtk_container_add (GTK_CONTAINER (sw), listview);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_widget_destroy (window);
return window;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<child>
<object class="GtkTreeExpander" id="expander">
<binding name="list-row">GtkListItem.item</binding>
<property name="child">
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel">
<property name="halign">start</property>
<binding name="label">expander.item:GtkDemo.title</binding>
</object>
</child>
<child>
<object class="GtkLabel">
<binding name="visible">!expander.list-row.expandable</binding>
<property name="halign">start</property>
<property name="use-markup">1</property>
<binding name="label">"&lt;small&gt;" + expander.item:GtkDemo.filename + "&lt;/small&gt;"</binding>
<style>
<class name="dim-label"/>
</style>
</object>
</child>
</object>
</property>
</object>
</child>
</template>
</interface>

View File

@@ -8,6 +8,7 @@
#include <gtk/gtk.h>
#include <glib/gstdio.h>
#include "award.h"
#include "demos.h"
static GtkWidget *info_view;
@@ -15,19 +16,99 @@ static GtkWidget *source_view;
static gchar *current_file = NULL;
static GtkWidget *window;
static GtkWidget *notebook;
static GtkWidget *treeview;
static GtkWidget *listview;
static GtkSingleSelection *selection;
static GtkWidget *headerbar;
enum {
NAME_COLUMN,
TITLE_COLUMN,
FILENAME_COLUMN,
FUNC_COLUMN,
STYLE_COLUMN,
NUM_COLUMNS
typedef struct _GtkDemo GtkDemo;
struct _GtkDemo
{
GObject parent_instance;
const char *name;
const char *title;
const char *filename;
GDoDemoFunc func;
GListModel *children_model;
};
enum {
PROP_0,
PROP_FILENAME,
PROP_NAME,
PROP_TITLE,
N_PROPS
};
# define GTK_TYPE_DEMO (gtk_demo_get_type ())
G_DECLARE_FINAL_TYPE (GtkDemo, gtk_demo, GTK, DEMO, GObject);
G_DEFINE_TYPE (GtkDemo, gtk_demo, G_TYPE_OBJECT);
static GParamSpec *properties[N_PROPS] = { NULL, };
static void
gtk_demo_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GtkDemo *self = GTK_DEMO (object);
switch (property_id)
{
case PROP_FILENAME:
g_value_set_string (value, self->filename);
break;
case PROP_NAME:
g_value_set_string (value, self->name);
break;
case PROP_TITLE:
g_value_set_string (value, self->title);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void gtk_demo_class_init (GtkDemoClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->get_property = gtk_demo_get_property;
properties[PROP_FILENAME] =
g_param_spec_string ("filename",
"filename",
"filename",
NULL,
G_PARAM_READABLE);
properties[PROP_NAME] =
g_param_spec_string ("name",
"name",
"name",
NULL,
G_PARAM_READABLE);
properties[PROP_TITLE] =
g_param_spec_string ("title",
"title",
"title",
NULL,
G_PARAM_READABLE);
g_object_class_install_properties (gobject_class, N_PROPS, properties);
}
static void gtk_demo_init (GtkDemo *self)
{
}
typedef struct _CallbackData CallbackData;
struct _CallbackData
{
@@ -35,6 +116,27 @@ struct _CallbackData
GtkTreePath *path;
};
static gboolean
gtk_demo_run (GtkDemo *self,
GtkWidget *window)
{
GtkWidget *result;
if (!self->func)
return FALSE;
result = self->func (window);
if (result == NULL)
return FALSE;
if (GTK_IS_WINDOW (result))
{
gtk_window_set_transient_for (GTK_WINDOW (result), GTK_WINDOW (window));
gtk_window_set_modal (GTK_WINDOW (result), TRUE);
}
return TRUE;
}
static void
activate_about (GSimpleAction *action,
GVariant *parameter,
@@ -111,69 +213,7 @@ activate_inspector (GSimpleAction *action,
gpointer user_data)
{
gtk_window_set_interactive_debugging (TRUE);
}
static void
window_closed_cb (GtkWidget *window, gpointer data)
{
CallbackData *cbdata = data;
GtkTreeIter iter;
PangoStyle style;
gtk_tree_model_get_iter (cbdata->model, &iter, cbdata->path);
gtk_tree_model_get (GTK_TREE_MODEL (cbdata->model), &iter,
STYLE_COLUMN, &style,
-1);
if (style == PANGO_STYLE_ITALIC)
gtk_tree_store_set (GTK_TREE_STORE (cbdata->model), &iter,
STYLE_COLUMN, PANGO_STYLE_NORMAL,
-1);
gtk_tree_path_free (cbdata->path);
g_free (cbdata);
}
static void
run_example_for_row (GtkWidget *window,
GtkTreeModel *model,
GtkTreeIter *iter)
{
PangoStyle style;
GDoDemoFunc func;
GtkWidget *demo;
gtk_tree_model_get (GTK_TREE_MODEL (model),
iter,
FUNC_COLUMN, &func,
STYLE_COLUMN, &style,
-1);
if (func)
{
gtk_tree_store_set (GTK_TREE_STORE (model),
iter,
STYLE_COLUMN, (style == PANGO_STYLE_ITALIC ? PANGO_STYLE_NORMAL : PANGO_STYLE_ITALIC),
-1);
demo = (func) (window);
if (demo != NULL)
{
CallbackData *cbdata;
cbdata = g_new (CallbackData, 1);
cbdata->model = model;
cbdata->path = gtk_tree_model_get_path (model, iter);
if (GTK_IS_WINDOW (demo))
{
gtk_window_set_transient_for (GTK_WINDOW (demo), GTK_WINDOW (window));
gtk_window_set_modal (GTK_WINDOW (demo), TRUE);
}
g_signal_connect (demo, "destroy",
G_CALLBACK (window_closed_cb), cbdata);
}
}
award ("demo-inspector");
}
static void
@@ -181,14 +221,10 @@ activate_run (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
GtkWidget *window = user_data;
GtkTreeSelection *selection;
GtkTreeModel *model;
GtkTreeIter iter;
GtkTreeListRow *row = gtk_single_selection_get_selected_item (selection);
GtkDemo *demo = gtk_tree_list_row_get_item (row);
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
if (gtk_tree_selection_get_selected (selection, &model, &iter))
run_example_for_row (window, model, &iter);
gtk_demo_run (demo, window);
}
/* Stupid syntax highlighting.
@@ -487,7 +523,7 @@ parse_chars (gchar *text,
}
/* While not as cool as c-mode, this will do as a quick attempt at highlighting */
static void
void
fontify (GtkTextBuffer *source_buffer)
{
GtkTextIter start_iter, next_iter, tmp_iter;
@@ -639,7 +675,7 @@ display_nothing (const char *resource)
str = g_strdup_printf ("The lazy GTK developers forgot to add a way to display the resource '%s'", resource);
widget = gtk_label_new (str);
gtk_label_set_line_wrap (GTK_LABEL (widget), TRUE);
gtk_label_set_wrap (GTK_LABEL (widget), TRUE);
g_free (str);
@@ -888,81 +924,72 @@ load_file (const gchar *demoname,
}
static void
selection_cb (GtkTreeSelection *selection,
GtkTreeModel *model)
selection_cb (GtkSingleSelection *selection,
GParamSpec *pspec,
gpointer user_data)
{
GtkTreeIter iter;
char *name;
char *filename;
char *title;
GtkTreeListRow *row = gtk_single_selection_get_selected_item (selection);
GtkDemo *demo = gtk_tree_list_row_get_item (row);
if (! gtk_tree_selection_get_selected (selection, NULL, &iter))
return;
if (demo->filename)
load_file (demo->name, demo->filename);
gtk_tree_model_get (model, &iter,
NAME_COLUMN, &name,
TITLE_COLUMN, &title,
FILENAME_COLUMN, &filename,
-1);
if (filename)
load_file (name, filename);
gtk_header_bar_set_title (GTK_HEADER_BAR (headerbar), title);
g_free (name);
g_free (title);
g_free (filename);
gtk_header_bar_set_title (GTK_HEADER_BAR (headerbar), demo->title);
}
static void
populate_model (GtkTreeModel *model)
static GListModel *
create_demo_model (void)
{
Demo *d = gtk_demos;
GListStore *store = g_list_store_new (GTK_TYPE_DEMO);
DemoData *demo = gtk_demos;
/* this code only supports 1 level of children. If we
* want more we probably have to use a recursing function.
*/
while (d->title)
while (demo->title)
{
Demo *children = d->children;
GtkTreeIter iter;
GtkDemo *d = GTK_DEMO (g_object_new (GTK_TYPE_DEMO, NULL));
DemoData *children = demo->children;
gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
d->name = demo->name;
d->title = demo->title;
d->filename = demo->filename;
d->func = demo->func;
gtk_tree_store_set (GTK_TREE_STORE (model),
&iter,
NAME_COLUMN, d->name,
TITLE_COLUMN, d->title,
FILENAME_COLUMN, d->filename,
FUNC_COLUMN, d->func,
STYLE_COLUMN, PANGO_STYLE_NORMAL,
-1);
g_list_store_append (store, d);
d++;
if (!children)
continue;
while (children->title)
if (children)
{
GtkTreeIter child_iter;
d->children_model = G_LIST_MODEL (g_list_store_new (GTK_TYPE_DEMO));
gtk_tree_store_append (GTK_TREE_STORE (model), &child_iter, &iter);
while (children->title)
{
GtkDemo *child = GTK_DEMO (g_object_new (GTK_TYPE_DEMO, NULL));
gtk_tree_store_set (GTK_TREE_STORE (model),
&child_iter,
NAME_COLUMN, children->name,
TITLE_COLUMN, children->title,
FILENAME_COLUMN, children->filename,
FUNC_COLUMN, children->func,
STYLE_COLUMN, PANGO_STYLE_NORMAL,
-1);
child->name = children->name;
child->title = children->title;
child->filename = children->filename;
child->func = children->func;
children++;
g_list_store_append (G_LIST_STORE (d->children_model), child);
children++;
}
}
demo++;
}
return G_LIST_MODEL (store);
}
static GListModel *
get_child_model (gpointer item,
gpointer user_data)
{
GtkDemo *demo = item;
if (demo->children_model)
return g_object_ref (G_LIST_MODEL (demo->children_model));
return NULL;
}
static void
@@ -982,22 +1009,6 @@ startup (GApplication *app)
g_object_unref (builder);
}
static void
row_activated_cb (GtkWidget *tree_view,
GtkTreePath *path,
GtkTreeViewColumn *column)
{
GtkTreeIter iter;
GtkWidget *window;
GtkTreeModel *model;
window = GTK_WIDGET (gtk_widget_get_root (tree_view));
model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_view));
gtk_tree_model_get_iter (model, &iter, path);
run_example_for_row (window, model, &iter);
}
static void
start_cb (GtkMenuItem *item, GtkWidget *scrollbar)
{
@@ -1024,34 +1035,45 @@ scrollbar_popup (GtkWidget *scrollbar, GtkWidget *menu)
return TRUE;
}
static void
listview_activate_cb (GtkCoverFlow *listview,
guint position,
gpointer user_data)
{
GtkTreeListRow *row = g_list_model_get_item (gtk_cover_flow_get_model (listview), position);
GtkDemo *demo = gtk_tree_list_row_get_item (row);
gtk_demo_run (demo, window);
}
static void
activate (GApplication *app)
{
GtkBuilder *builder;
GtkWindow *window;
GtkWidget *widget;
GtkTreeModel *model;
GtkTreeIter iter;
GError *error = NULL;
GtkWidget *sw;
GtkWidget *scrollbar;
GtkWidget *menu;
GtkWidget *item;
GListModel *listmodel;
GtkTreeListModel *treemodel;
static GActionEntry win_entries[] = {
{ "run", activate_run, NULL, NULL, NULL }
};
builder = gtk_builder_new ();
gtk_builder_add_callback_symbol (builder, "listview_activate_cb", G_CALLBACK (listview_activate_cb));
gtk_builder_add_from_resource (builder, "/ui/main.ui", &error);
if (error != NULL)
{
g_critical ("%s", error->message);
exit (1);
}
gtk_builder_connect_signals (builder, NULL);
window = (GtkWindow *)gtk_builder_get_object (builder, "window");
gtk_application_add_window (GTK_APPLICATION (app), window);
window = (GtkWidget *)gtk_builder_get_object (builder, "window");
gtk_application_add_window (GTK_APPLICATION (app), GTK_WINDOW (window));
g_action_map_add_action_entries (G_ACTION_MAP (window),
win_entries, G_N_ELEMENTS (win_entries),
window);
@@ -1061,8 +1083,7 @@ activate (GApplication *app)
info_view = (GtkWidget *)gtk_builder_get_object (builder, "info-textview");
source_view = (GtkWidget *)gtk_builder_get_object (builder, "source-textview");
headerbar = (GtkWidget *)gtk_builder_get_object (builder, "headerbar");
treeview = (GtkWidget *)gtk_builder_get_object (builder, "treeview");
model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview));
listview = (GtkWidget *)gtk_builder_get_object (builder, "listview");
sw = (GtkWidget *)gtk_builder_get_object (builder, "source-scrolledwindow");
scrollbar = gtk_scrolled_window_get_vscrollbar (GTK_SCROLLED_WINDOW (sw));
@@ -1081,17 +1102,19 @@ activate (GApplication *app)
load_file (gtk_demos[0].name, gtk_demos[0].filename);
populate_model (model);
listmodel = create_demo_model ();
treemodel = gtk_tree_list_model_new (FALSE,
G_LIST_MODEL (listmodel),
FALSE,
get_child_model,
NULL,
NULL);
selection = gtk_single_selection_new (G_LIST_MODEL (treemodel));
g_signal_connect (selection, "notify::selected-item", G_CALLBACK (selection_cb), NULL);
gtk_cover_flow_set_model (GTK_COVER_FLOW (listview),
G_LIST_MODEL (selection));
g_signal_connect (treeview, "row-activated", G_CALLBACK (row_activated_cb), model);
widget = (GtkWidget *)gtk_builder_get_object (builder, "treeview-selection");
g_signal_connect (widget, "changed", G_CALLBACK (selection_cb), model);
gtk_tree_model_get_iter_first (gtk_tree_view_get_model (GTK_TREE_VIEW (treeview)), &iter);
gtk_tree_selection_select_iter (GTK_TREE_SELECTION (widget), &iter);
gtk_tree_view_collapse_all (GTK_TREE_VIEW (treeview));
award ("demo-start");
gtk_widget_show (GTK_WIDGET (window));
@@ -1108,7 +1131,7 @@ auto_quit (gpointer data)
static void
list_demos (void)
{
Demo *d, *c;
DemoData *d, *c;
d = gtk_demos;
@@ -1135,7 +1158,7 @@ command_line (GApplication *app,
const gchar *name = NULL;
gboolean autoquit = FALSE;
gboolean list = FALSE;
Demo *d, *c;
DemoData *d, *c;
GDoDemoFunc func = 0;
GtkWidget *window, *demo;

View File

@@ -28,7 +28,6 @@
<property name="default-width">800</property>
<property name="default-height">600</property>
<property name="title">GTK Demo</property>
<signal name="destroy" handler="gtk_main_quit" swapped="no"/>
<child type="titlebar">
<object class="GtkHeaderBar" id="headerbar">
<property name="show-title-buttons">1</property>
@@ -66,32 +65,15 @@
<property name="can-focus">1</property>
<property name="hscrollbar-policy">never</property>
<property name="min-content-width">150</property>
<child>
<object class="GtkTreeView" id="treeview">
<property name="can-focus">1</property>
<property name="model">treestore</property>
<property name="headers-visible">0</property>
<child internal-child="selection">
<object class="GtkTreeSelection" id="treeview-selection">
<property name="mode">browse</property>
<object class="GtkCoverFlow" id="listview">
<signal name="activate" handler="listview_activate_cb" swapped="no" />
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="resource">/ui/main-listitem.ui</property>
</object>
</child>
<child>
<object class="GtkTreeViewColumn">
<child>
<object class="GtkCellRendererText"/>
<attributes>
<attribute name="style">4</attribute>
<attribute name="text">1</attribute>
</attributes>
</child>
<child>
<object class="GtkCellRendererText">
<property name="text"> </property>
</object>
</child>
</object>
</child>
</property>
</object>
</child>
</object>

View File

@@ -3,11 +3,15 @@
demos = files([
'application_demo.c',
'assistant.c',
'awardview.c',
'builder.c',
'changedisplay.c',
'clipboard.c',
'colorsel.c',
'combobox.c',
'constraints.c',
'constraints2.c',
'constraints3.c',
'css_accordion.c',
'css_basics.c',
'css_blendmodes.c',
@@ -25,11 +29,13 @@ demos = files([
'filtermodel.c',
'fishbowl.c',
'fixed.c',
'fontrendering.c',
'foreigndrawing.c',
'gestures.c',
'glarea.c',
'headerbar.c',
'hypertext.c',
'iconscroll.c',
'iconview.c',
'iconview_edit.c',
'images.c',
@@ -38,6 +44,10 @@ demos = files([
'listbox.c',
'flowbox.c',
'list_store.c',
'listview_filebrowser.c',
'listview_minesweeper.c',
'listview_settings.c',
'listview_weather.c',
'markup.c',
'menus.c',
'modelbutton.c',
@@ -80,6 +90,7 @@ demos = files([
gtkdemo_deps = [ libgtk_dep, ]
extra_demo_sources = files(['main.c',
'award.c',
'gtkfishbowl.c',
'fontplane.c',
'gtkgears.c',

View File

@@ -378,7 +378,7 @@
378|GTK+ and friends|GTKtoolkit|#GNUStep gets #GTK+ theming http://is.gd/95vHl more at http://is.gd/95wt8|1267029498|0||0|1
379|GTK+ and friends|GTKtoolkit|GTK+ 2.19.6 released: http://mail.gnome.org/archives/gtk-devel-list/2010-February/msg00050.html #gtk|1266966985|0||0|0
380|GTK+ and friends|GTKtoolkit|Did you know that #GTK+ is the official toolkit for the #LiMo software stack? http://bit.ly/cuEdHx|1266925406|0||0|0
381|GTK+ and friends|GTKtoolkit|@lmedinas publishes a #javascript #example on how to put an status icon with #Gtk+ http://bit.ly/9py1uC Thanks a lot Luis!|1266886644|0||1|1
381|GTK+ and friends|GTKtoolkit|@lmedinas publishes a #javascript #example on how to put a status icon with #Gtk+ http://bit.ly/9py1uC Thanks a lot Luis!|1266886644|0||1|1
382|GTK+ and friends|GTKtoolkit|♺ @ebassi: I should really finish up the GDom API as well|1266880653|0||0|0
383|GTK+ and friends|GTKtoolkit|♺ @ebassi: I hope to work on this for the next GIO release, and the GTK+ side for 3.0|1266880641|0||0|0
384|GTK+ and friends|GTKtoolkit|♺ @ebassi: just updated the ApplicationClass design wiki page with the stuff @Cwiiis did for Mx - http://bit.ly/cfAOJk|1266880559|0||0|0

View File

@@ -14,34 +14,19 @@
<child>
<object class="GtkMenuButton">
<property name="popover">thing_a</property>
<child>
<object class="GtkLabel">
<property name="label">Color</property>
<property name="hexpand">1</property>
</object>
</child>
<property name="label">Color</property>
</object>
</child>
<child>
<object class="GtkMenuButton">
<property name="popover">thing_b</property>
<child>
<object class="GtkLabel">
<property name="label">Flavors</property>
<property name="hexpand">1</property>
</object>
</child>
<property name="label">Flavors</property>
</object>
</child>
<child>
<object class="GtkMenuButton">
<property name="popover">thing_c</property>
<child>
<object class="GtkLabel">
<property name="label">Tools</property>
<property name="hexpand">1</property>
</object>
</child>
<property name="label">Tools</property>
</object>
</child>
</object>
@@ -57,7 +42,6 @@
<property name="action-name">win.color</property>
<property name="action-target">&apos;red&apos;</property>
<property name="text">Red</property>
<property name="inverted">1</property>
</object>
</child>
<child>
@@ -65,7 +49,6 @@
<property name="action-name">win.color</property>
<property name="action-target">&apos;green&apos;</property>
<property name="text">Green</property>
<property name="inverted">1</property>
</object>
</child>
<child>
@@ -73,7 +56,6 @@
<property name="action-name">win.color</property>
<property name="action-target">&apos;blue&apos;</property>
<property name="text">Blue</property>
<property name="inverted">1</property>
</object>
</child>
</object>

View File

@@ -6,7 +6,7 @@
* GTK uses for videos. This allows treating the icon like a
* regular video, so we can for example attach controls to it.
*
* After all, what good is an media_stream if one cannot pause
* After all, what good is a media_stream if one cannot pause
* it.
*/

View File

@@ -11,6 +11,8 @@
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include "award.h"
static GtkWidget *entry;
static GtkWidget *entry2;
static GtkWidget *button;
@@ -25,6 +27,18 @@ update_button (GObject *object,
gtk_widget_set_sensitive (button,
text[0] != '\0' && g_str_equal (text, text2));
if (g_str_equal (text, text2) &&
g_ascii_strcasecmp (text, "12345") == 0)
award ("password-best");
}
static void
button_pressed (GtkButton *button,
GtkWidget *window)
{
award ("password-correct");
gtk_widget_destroy (window);
}
GtkWidget *
@@ -72,7 +86,7 @@ do_password_entry (GtkWidget *do_widget)
button = gtk_button_new_with_mnemonic ("_Done");
gtk_style_context_add_class (gtk_widget_get_style_context (button), "suggested-action");
g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_widget_destroy), window);
g_signal_connect (button, "clicked", G_CALLBACK (button_pressed), window);
gtk_widget_set_sensitive (button, FALSE);
gtk_header_bar_pack_end (GTK_HEADER_BAR (header), button);

View File

@@ -54,10 +54,7 @@ do_sidebar (GtkWidget *do_widget)
stack = gtk_stack_new ();
gtk_stack_set_transition_type (GTK_STACK (stack), GTK_STACK_TRANSITION_TYPE_SLIDE_UP_DOWN);
gtk_stack_sidebar_set_stack (GTK_STACK_SIDEBAR (sidebar), GTK_STACK (stack));
/* Separator between sidebar and stack */
widget = gtk_separator_new (GTK_ORIENTATION_VERTICAL);
gtk_container_add (GTK_CONTAINER(box), widget);
gtk_widget_set_hexpand (stack, TRUE);
gtk_container_add (GTK_CONTAINER (box), stack);
@@ -66,6 +63,7 @@ do_sidebar (GtkWidget *do_widget)
if (i == 0)
{
widget = gtk_image_new_from_icon_name ("org.gtk.Demo4");
gtk_style_context_add_class (gtk_widget_get_style_context (widget), "icon-dropshadow");
gtk_image_set_pixel_size (GTK_IMAGE (widget), 256);
}
else

View File

@@ -11,6 +11,9 @@
#include "puzzlepiece.h"
#include "paintable.h"
/* Give out awards */
#include "award.h"
static GtkWidget *window = NULL;
static GtkWidget *frame = NULL;
static GtkWidget *choices = NULL;
@@ -156,6 +159,14 @@ check_solved (GtkWidget *grid)
picture = gtk_grid_get_child_at (GTK_GRID (grid), pos_x, pos_y);
gtk_picture_set_paintable (GTK_PICTURE (picture), piece);
/* Hand out a bunch of awards
*/
award ("puzzle-solve");
if ((gdk_paintable_get_flags (piece) & GDK_PAINTABLE_STATIC_CONTENTS) == 0)
award ("puzzle-solve-animated");
if (height * width > 20)
award ("puzzle-solve-large");
return TRUE;
}
@@ -401,6 +412,18 @@ add_choice (GtkWidget *choices,
gtk_container_add (GTK_CONTAINER (choices), icon);
}
static void
widget_destroyed (GtkWidget *widget,
GtkWidget **widget_pointer)
{
if (widget_pointer)
*widget_pointer = NULL;
if (!solved)
award ("puzzle-give-up");
}
GtkWidget *
do_sliding_puzzle (GtkWidget *do_widget)
{
@@ -469,7 +492,7 @@ do_sliding_puzzle (GtkWidget *do_widget)
gtk_window_set_titlebar (GTK_WINDOW (window), header);
gtk_window_set_default_size (GTK_WINDOW (window), 400, 300);
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed), &window);
G_CALLBACK (widget_destroyed), &window);
frame = gtk_aspect_frame_new (NULL, 0.5, 0.5, (float) gdk_paintable_get_intrinsic_aspect_ratio (puzzle), FALSE);
gtk_container_add (GTK_CONTAINER (window), frame);

View File

@@ -128,18 +128,16 @@ insert_text (GtkTextBuffer *buffer)
{
GtkTextIter iter;
GtkTextIter start, end;
GdkPixbuf *pixbuf;
GdkTexture *texture;
GtkIconTheme *icon_theme;
icon_theme = gtk_icon_theme_get_default ();
pixbuf = gtk_icon_theme_load_icon (icon_theme,
"gtk3-demo",
32,
GTK_ICON_LOOKUP_GENERIC_FALLBACK,
NULL);
g_assert (pixbuf);
texture = gdk_texture_new_for_pixbuf (pixbuf);
texture = GDK_TEXTURE (gtk_icon_theme_load_icon (icon_theme,
"gtk3-demo",
32,
GTK_ICON_LOOKUP_GENERIC_FALLBACK,
NULL));
g_assert (texture);
/* get start of buffer; each insertion will revalidate the
* iterator to point to just after the inserted text.
@@ -379,7 +377,6 @@ insert_text (GtkTextBuffer *buffer)
gtk_text_buffer_get_bounds (buffer, &start, &end);
gtk_text_buffer_apply_tag_by_name (buffer, "word_wrap", &start, &end);
g_object_unref (pixbuf);
g_object_unref (texture);
}

View File

@@ -285,7 +285,7 @@ user-trash=The icon for the user's “Trash” place in the file system
user-trash-full=The icon for the user's “Trash” in the file system, when there are items in the “Trash” waiting for disposal or recovery
emblem-system=The icon used as an emblem for directories that contain system libraries, settings, and data
avatar-default=The generic avatar icon, which is used to represent a user that doesn't have a personalized avatar
emblem-synchronizing=The icon used as an emblem to indicate that a a synchronizing operation is in process
emblem-synchronizing=The icon used as an emblem to indicate that a synchronizing operation is in process
emblem-shared=The icon used as an emblem for files and directories that are shared to other users
help-browser=The icon used for the desktop's help browsing application

View File

@@ -81,11 +81,14 @@ get_icon (GtkWidget *image, const gchar *name, gint size)
{
GtkIconInfo *info;
GtkStyleContext *context;
GdkTexture *texture;
GdkPixbuf *pixbuf;
context = gtk_widget_get_style_context (image);
info = gtk_icon_theme_lookup_icon (gtk_icon_theme_get_default (), name, size, 0);
pixbuf = gtk_icon_info_load_symbolic_for_context (info, context, NULL, NULL);
texture = GDK_TEXTURE (gtk_icon_info_load_symbolic_for_context (info, context, NULL, NULL));
pixbuf = gdk_pixbuf_get_from_texture (texture);
g_object_unref (texture);
g_object_unref (info);
return pixbuf;

View File

@@ -1,3 +1,4 @@
subdir('constraint-editor')
subdir('gtk-demo')
subdir('icon-browser')
subdir('node-editor')

View File

@@ -26,9 +26,9 @@
static const char *css =
"textview.editor {"
" color: rgb(192, 197, 206);"
" caret-color: white;"
" caret-color: currentColor;"
"}"
"textview.editor text {"
"textview.editor > text {"
" background-color: rgb(43, 48, 59);"
"}"
;

View File

@@ -707,6 +707,14 @@ static void
node_editor_window_unrealize (GtkWidget *widget)
{
NodeEditorWindow *self = NODE_EDITOR_WINDOW (widget);
guint i;
for (i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (self->renderers)); i ++)
{
gpointer item = g_list_model_get_item (G_LIST_MODEL (self->renderers), i);
gsk_renderer_unrealize (gtk_renderer_paintable_get_renderer (item));
g_object_unref (item);
}
g_list_store_remove_all (self->renderers);

View File

@@ -1003,6 +1003,9 @@ populate_flowbox (GtkWidget *flowbox)
while ((name = g_dir_read_name (dir)) != NULL)
{
if (g_str_has_suffix (name, ".xml"))
continue;
filename = g_build_filename (location, name, NULL);
file = g_file_new_for_path (filename);
stream = G_INPUT_STREAM (g_file_read (file, NULL, &error));
@@ -1017,7 +1020,7 @@ populate_flowbox (GtkWidget *flowbox)
bd = g_new (BackgroundData, 1);
bd->flowbox = flowbox;
bd->filename = filename;
gdk_pixbuf_new_from_stream_at_scale_async (stream, 110, 110, TRUE, NULL,
gdk_pixbuf_new_from_stream_at_scale_async (stream, 110, 110, TRUE, NULL,
background_loaded_cb, bd);
}
@@ -1405,8 +1408,10 @@ text_view_add_to_context_menu (GtkTextView *text_view)
item = g_menu_item_new (_("Underline"), "format.underline");
g_menu_item_set_attribute (item, "touch-icon", "s", "format-text-underline-symbolic");
g_menu_append_item (G_MENU (menu), item);
g_object_unref (item);
gtk_text_view_set_extra_menu (text_view, G_MENU_MODEL (menu));
g_object_unref (menu);
g_signal_connect (gtk_text_view_get_buffer (text_view), "changed", G_CALLBACK (text_changed), NULL);
g_signal_connect (gtk_text_view_get_buffer (text_view), "mark-set", G_CALLBACK (text_changed), NULL);
@@ -1601,14 +1606,14 @@ reset_icon_size (GtkWidget *iv)
gtk_widget_queue_resize (iv);
}
static gchar *
scale_format_value_blank (GtkScale *scale, gdouble value)
static char *
scale_format_value_blank (GtkScale *scale, double value, gpointer user_data)
{
return g_strdup (" ");
}
static gchar *
scale_format_value (GtkScale *scale, gdouble value)
static char *
scale_format_value (GtkScale *scale, double value, gpointer user_data)
{
return g_strdup_printf ("%0.*f", 1, value);
}
@@ -1647,7 +1652,7 @@ set_up_context_popover (GtkWidget *widget,
GtkWidget *popover = gtk_popover_menu_new_from_model (widget, model);
GtkGesture *gesture;
g_object_set (popover, "has-arrow", FALSE, NULL);
gtk_popover_set_has_arrow (GTK_POPOVER (popover), FALSE);
gesture = gtk_gesture_click_new ();
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), GDK_BUTTON_SECONDARY);
g_signal_connect (gesture, "pressed", G_CALLBACK (clicked_cb), popover);
@@ -1707,7 +1712,7 @@ activate (GApplication *app)
gtk_css_provider_load_from_resource (provider, "/org/gtk/WidgetFactory4/widget-factory.css");
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
GTK_STYLE_PROVIDER (provider),
GTK_STYLE_PROVIDER_PRIORITY_USER);
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
g_object_unref (provider);
builder = gtk_builder_new_from_resource ("/org/gtk/WidgetFactory4/widget-factory.ui");
@@ -1722,8 +1727,6 @@ activate (GApplication *app)
gtk_builder_add_callback_symbol (builder, "increase_icon_size", (GCallback)increase_icon_size);
gtk_builder_add_callback_symbol (builder, "decrease_icon_size", (GCallback)decrease_icon_size);
gtk_builder_add_callback_symbol (builder, "reset_icon_size", (GCallback)reset_icon_size);
gtk_builder_add_callback_symbol (builder, "scale_format_value", (GCallback)scale_format_value);
gtk_builder_add_callback_symbol (builder, "scale_format_value_blank", (GCallback)scale_format_value_blank);
gtk_builder_add_callback_symbol (builder, "osd_frame_pressed", (GCallback)osd_frame_pressed);
gtk_builder_connect_signals (builder, NULL);
@@ -1943,6 +1946,12 @@ activate (GApplication *app)
widget = (GtkWidget *)gtk_builder_get_object (builder, "extra_info_entry");
g_timeout_add (100, (GSourceFunc)pulse_it, widget);
widget = (GtkWidget *)gtk_builder_get_object (builder, "scale3");
gtk_scale_set_format_value_func (GTK_SCALE (widget), scale_format_value, NULL, NULL);
widget = (GtkWidget *)gtk_builder_get_object (builder, "scale4");
gtk_scale_set_format_value_func (GTK_SCALE (widget), scale_format_value_blank, NULL, NULL);
widget = (GtkWidget *)gtk_builder_get_object (builder, "box_for_context");
model = (GMenuModel *)gtk_builder_get_object (builder, "new_style_context_menu_model");
set_up_context_popover (widget, model);

View File

@@ -1019,7 +1019,6 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
<property name="fill-level">75</property>
<property name="digits">-1</property>
<property name="halign">end</property>
<signal name="format-value" handler="scale_format_value"/>
</object>
</child>
<child>
@@ -1033,7 +1032,6 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
<property name="fill-level">75</property>
<property name="digits">-1</property>
<property name="halign">start</property>
<signal name="format-value" handler="scale_format_value_blank"/>
</object>
</child>
</object>
@@ -1728,15 +1726,11 @@ microphone-sensitivity-medium-symbolic</property>
</object>
</child>
<child>
<object class="GtkImage">
<property name="icon-name">object-select-symbolic</property>
<object class="GtkSpinButton">
<property name="adjustment">adjustment1</property>
<property name="hexpand">1</property>
<property name="halign">end</property>
<property name="valign">center</property>
<property name="margin-top">6</property>
<property name="margin-bottom">6</property>
<property name="margin-start">12</property>
<property name="margin-end">12</property>
<property name="opacity">0</property>
</object>
</child>
</object>
@@ -1911,11 +1905,11 @@ microphone-sensitivity-medium-symbolic</property>
</object>
</child>
<child>
<object class="GtkMenuItem" id="togglesmenuitem">
<property name="label">Checks &amp; Radios</property>
<object class="GtkMenuItem" id="checksmenuitem">
<property name="label">_Checks</property>
<property name="use-underline">1</property>
<child type="submenu">
<object class="GtkMenu" id="togglessubmenu">
<object class="GtkMenu" id="checkssubmenu">
<child>
<object class="GtkCheckMenuItem" id="checkmenuitem1">
<property name="label">_Check</property>
@@ -1959,9 +1953,16 @@ microphone-sensitivity-medium-symbolic</property>
<property name="use-underline">1</property>
</object>
</child>
<child>
<object class="GtkSeparatorMenuItem" id="separatormenuitem"/>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkMenuItem" id="radiosmenuitem">
<property name="label">_Radios</property>
<property name="use-underline">1</property>
<child type="submenu">
<object class="GtkMenu" id="radiossubmenu">
<child>
<object class="GtkRadioMenuItem" id="radiomenuitem1">
<property name="label">_Radio</property>
@@ -2013,6 +2014,7 @@ microphone-sensitivity-medium-symbolic</property>
</child>
</object>
</child>
FOO
<child>
<object class="GtkMenuItem" id="menuitem3">
<property name="label" translatable="yes">View</property>
@@ -2120,7 +2122,7 @@ microphone-sensitivity-medium-symbolic</property>
<object class="GtkInfoBar" id="infobar">
<property name="visible">0</property>
<property name="show-close-button">1</property>
<child internal-child="content_area">
<child>
<object class="GtkBox">
<child>
<object class="GtkLabel">
@@ -2131,9 +2133,14 @@ microphone-sensitivity-medium-symbolic</property>
</child>
</object>
</child>
<child>
<object class="GtkSeparator">
<property name="orientation">horizontal</property>
</object>
</child>
<child>
<object class="GtkScrolledWindow">
<property name="shadow-type">in</property>
<property name="shadow-type">none</property>
<property name="vexpand">1</property>
<child>
<object class="MyTextView" id="text3">
@@ -2147,6 +2154,11 @@ microphone-sensitivity-medium-symbolic</property>
</child>
</object>
</child>
<child>
<object class="GtkSeparator">
<property name="orientation">horizontal</property>
</object>
</child>
<child>
<object class="GtkStatusbar" id="statusbar"/>
</child>
@@ -3435,6 +3447,7 @@ bad things might happen.</property>
<property name="halign">end</property>
<property name="icon-name">emblem-system-symbolic</property>
<property name="menu-model">gear_menu</property>
<property name="tooltip-text">This is a menu button</property>
<layout>
<property name="left-attach">1</property>
<property name="top-attach">3</property>
@@ -3593,21 +3606,18 @@ bad things might happen.</property>
<object class="GtkModelButton">
<property name="icon"><object class="GThemedIcon"><property name="name">edit-cut-symbolic</property></object></property>
<property name="iconic">1</property>
<property name="relief">none</property>
</object>
</child>
<child>
<object class="GtkModelButton">
<property name="icon"><object class="GThemedIcon"><property name="name">edit-copy-symbolic</property></object></property>
<property name="iconic">1</property>
<property name="relief">none</property>
</object>
</child>
<child>
<object class="GtkModelButton">
<property name="icon"><object class="GThemedIcon"><property name="name">edit-paste-symbolic</property></object></property>
<property name="iconic">1</property>
<property name="relief">none</property>
</object>
</child>
</object>
@@ -3945,7 +3955,7 @@ bad things might happen.</property>
</section>
<section>
<submenu>
<attribute name="label" translatable="yes">Checks &amp; Radios</attribute>
<attribute name="label" translatable="yes">C_hecks</attribute>
<section>
<item>
<attribute name="label" translatable="yes">Check</attribute>
@@ -3969,6 +3979,9 @@ bad things might happen.</property>
<attribute name="hidden-when">action-missing</attribute>
</item>
</section>
</submenu>
<submenu>
<attribute name="label" translatable="yes">_Radios</attribute>
<section>
<item>
<attribute name="label" translatable="yes">Radio</attribute>

View File

@@ -1128,6 +1128,7 @@ gdk_monitor_get_width_mm
gdk_monitor_get_height_mm
gdk_monitor_get_manufacturer
gdk_monitor_get_model
gdk_monitor_get_connector
gdk_monitor_get_scale_factor
gdk_monitor_get_refresh_rate
GdkSubpixelLayout

View File

@@ -99,7 +99,7 @@ if wayland_enabled
src_dir += [ gdkwayland_inc ]
endif
if get_option('documentation')
if get_option('gtk_doc')
configure_file(input: 'version.xml.in', output: 'version.xml', configuration: version_conf)
gnome.gtkdoc('gdk4',

View File

@@ -34,7 +34,7 @@ private_headers = [
images = [
]
if get_option('documentation')
if get_option('gtk_doc')
configure_file(input: 'version.xml.in', output: 'version.xml', configuration: version_conf)
gnome.gtkdoc('gsk4',

View File

@@ -258,9 +258,11 @@
</para>
<para>
Actions are added to their relevant scope (application or
window) either using the GActionMap interface, or by using
gtk_widget_insert_action_group().
Actions are added to their relevant scope (application,
window or widget) either using the GActionMap interface,
or by using gtk_widget_insert_action_group(). Actions that
will be the same for all instances of a widget class can
be added globally using gtk_widget_class_install_action().
</para>
</refsect2>
@@ -317,8 +319,8 @@
</para>
<para>
Another of obtaining widgets that are connected to actions is
to create a menu using a GMenu menu model. GMenu provides an
Another way of obtaining widgets that are connected to actions
is to create a menu using a GMenu menu model. GMenu provides an
abstract way to describe typical menus: nested groups of items
where each item can have a label, and icon, and an action.
</para>
@@ -364,6 +366,25 @@
(typically a GtkWindow, GtkDialog or GtkPopover)
</para></listitem>
</varlistentry>
<varlistentry>
<term>clipboard.cut, clipboard.copy, clipboard.paste</term>
<listitem><para>Clipboard operations on entries, text view
and labels, typically used in the context menu
</para></listitem>
</varlistentry>
<varlistentry>
<term>selection.delete, selection.select-all</term>
<listitem><para>Selection operations on entries, text view
and labels
</para></listitem>
</varlistentry>
<varlistentry>
<term>color.select, color.customize</term>
<listitem><para>Operations on colors in GtkColorChooserWidget.
These actions are unusual in that they have the non-trivial
parameter type (dddd).
</para></listitem>
</varlistentry>
</variablelist>
</para>

View File

@@ -355,8 +355,8 @@ How to compile GTK itself
</group>
<sbr/>
<group>
<arg choice="plain">-Ddocumentation=true</arg>
<arg choice="plain">-Ddocumentation=false</arg>
<arg choice="plain">-Dgtk_doc=true</arg>
<arg choice="plain">-Dgtk_doc=false</arg>
</group>
<sbr/>
<group>
@@ -382,7 +382,7 @@ How to compile GTK itself
</formalpara>
<formalpara>
<title><systemitem>documentation</systemitem> and
<title><systemitem>gtk_doc</systemitem> and
<systemitem>man-pages</systemitem></title>
<para>
@@ -394,7 +394,7 @@ How to compile GTK itself
<application>gtk-doc</application> installed and
are modifying GTK, you may want to enable
<application>gtk-doc</application> support by passing
in <systemitem>documentation</systemitem>.
in <systemitem>gtk_doc</systemitem>.
</para>
<para>
Additionally, some tools provided by GTK have their own

View File

@@ -51,7 +51,9 @@
<xi:include href="xml/gtksortlistmodel.xml" />
<xi:include href="xml/gtktreelistmodel.xml" />
<xi:include href="xml/gtkselectionmodel.xml" />
<xi:include href="xml/gtknoselection.xml" />
<xi:include href="xml/gtksingleselection.xml" />
<xi:include href="xml/gtkdirectorylist.xml" />
</chapter>
<chapter id="Application">
@@ -86,6 +88,9 @@
<xi:include href="xml/gtkrevealer.xml" />
<xi:include href="xml/gtklistbox.xml" />
<xi:include href="xml/gtkflowbox.xml" />
<xi:include href="xml/gtklistview.xml" />
<xi:include href="xml/gtkgridview.xml" />
<xi:include href="xml/gtktreeexpander.xml" />
<xi:include href="xml/gtkstack.xml" />
<xi:include href="xml/gtkstackswitcher.xml" />
<xi:include href="xml/gtkstacksidebar.xml" />
@@ -109,6 +114,9 @@
<xi:include href="xml/gtkcustomlayout.xml" />
<xi:include href="xml/gtkfixedlayout.xml" />
<xi:include href="xml/gtkgridlayout.xml" />
<xi:include href="xml/gtkconstraintlayout.xml" />
<xi:include href="xml/gtkconstraint.xml" />
<xi:include href="xml/gtkconstraintguide.xml" />
</chapter>
<chapter id="DisplayWidgets">

View File

@@ -136,6 +136,7 @@ gtk_accel_map_get_type
GtkAccelLabel
gtk_accel_label_new
gtk_accel_label_set_accel_closure
gtk_accel_label_get_accel_closure
gtk_accel_label_get_accel_widget
gtk_accel_label_set_accel_widget
gtk_accel_label_get_accel_width
@@ -340,6 +341,30 @@ GTK_CENTER_BOX_GET_CLASS
gtk_center_box_get_type
</SECTION>
<SECTION>
<FILE>gtkcenterlayout</FILE>
<TITLE>GtkCenterLayout</TITLE>
GtkCenterLayout
gtk_center_layout_new
gtk_center_layout_set_start_widget
gtk_center_layout_set_center_widget
gtk_center_layout_set_end_widget
gtk_center_layout_get_start_widget
gtk_center_layout_get_center_widget
gtk_center_layout_get_end_widget
gtk_center_layout_set_baseline_position
gtk_center_layout_get_baseline_position
<SUBSECTION Private>
GTK_TYPE_CENTER_layout
GTK_CENTER_LAYOUT
GTK_CENTER_LAYOUT_CLASS
GTK_IS_CENTER_LAYOUT
GTK_IS_CENTER_LAYOUT_CLASS
GTK_CENTER_LAYOUT_GET_CLASS
<SUBSECTION Private>
gtk_center_layout_get_type
</SECTION>
<SECTION>
<FILE>gtklistbox</FILE>
<TITLE>GtkListBox</TITLE>
@@ -440,12 +465,23 @@ GTK_TYPE_SELECTION_MODEL
gtk_selection_model_get_type
</SECTION>
<SECTION>
<FILE>gtknoselection</FILE>
<TITLE>GtkNoSelection</TITLE>
GtkNoSelection
gtk_no_selection_new
gtk_no_selection_get_model
<SUBSECTION Private>
gtk_no_selection_get_type
</SECTION>
<SECTION>
<FILE>gtksingleselection</FILE>
<TITLE>GtkSingleSelection</TITLE>
GtkSingleSelection
GTK_INVALID_LIST_POSITION
gtk_single_selection_new
gtk_single_selection_get_model
gtk_single_selection_get_selected
gtk_single_selection_set_selected
gtk_single_selection_get_selected_item
@@ -457,6 +493,114 @@ gtk_single_selection_set_can_unselect
gtk_single_selection_get_type
</SECTION>
<SECTION>
<FILE>gtklistitem</FILE>
<TITLE>GtkListItem</TITLE>
GtkListItem
gtk_list_item_get_item
gtk_list_item_get_position
gtk_list_item_get_selected
gtk_list_item_get_selectable
gtk_list_item_set_selectable
<SUBSECTION Standard>
GTK_LIST_ITEM
GTK_LIST_ITEM_CLASS
GTK_LIST_ITEM_GET_CLASS
GTK_IS_LIST_ITEM
GTK_IS_LIST_ITEM_CLASS
GTK_TYPE_LIST_ITEM
<SUBSECTION Private>
gtk_list_item_get_type
</SECTION>
<SECTION>
<FILE>gtklistview</FILE>
<TITLE>GtkListView</TITLE>
GtkListView
gtk_list_view_new
gtk_list_view_new_with_factory
gtk_list_view_set_factory
gtk_list_view_get_factory
gtk_list_view_set_model
gtk_list_view_get_model
gtk_list_view_set_show_separators
gtk_list_view_get_show_separators
<SUBSECTION Standard>
GTK_LIST_VIEW
GTK_LIST_VIEW_CLASS
GTK_LIST_VIEW_GET_CLASS
GTK_IS_LIST_VIEW
GTK_IS_LIST_VIEW_CLASS
GTK_TYPE_LIST_VIEW
<SUBSECTION Private>
gtk_list_view_get_type
</SECTION>
<SECTION>
<FILE>gtkcolumnview</FILE>
<TITLE>GtkColumnView</TITLE>
GtkColumnView
gtk_column_view_new
gtk_column_view_get_columns
gtk_column_view_get_model
gtk_column_view_set_model
gtk_column_view_get_show_separators
gtk_column_view_set_show_separators
<SUBSECTION Standard>
GTK_COLUMN_VIEW
GTK_COLUMN_VIEW_CLASS
GTK_COLUMN_VIEW_GET_CLASS
GTK_IS_COLUMN_VIEW
GTK_IS_COLUMN_VIEW_CLASS
GTK_TYPE_COLUMN_VIEW
<SUBSECTION Private>
gtk_column_view_get_type
</SECTION>
<SECTION>
<FILE>gtkcolumnviewcolumn</FILE>
<TITLE>GtkColumnViewColumn</TITLE>
GtkColumnViewColumn
gtk_column_view_column_new
gtk_column_view_column_new_with_factory
gtk_column_view_column_get_column_view
gtk_column_view_column_set_factory
gtk_column_view_column_get_factory
gtk_column_view_column_set_title
gtk_column_view_column_get_title
<SUBSECTION Standard>
GTK_COLUMN_VIEW_COLUMN
GTK_COLUMN_VIEW_COLUMN_CLASS
GTK_COLUMN_VIEW_COLUMN_GET_CLASS
GTK_IS_COLUMN_VIEW_COLUMN
GTK_IS_COLUMN_VIEW_COLUMN_CLASS
GTK_TYPE_COLUMN_VIEW_COLUMN
<SUBSECTION Private>
gtk_column_view_column_get_type
</SECTION>
<SECTION>
<FILE>gtkgridview</FILE>
<TITLE>GtkGridView</TITLE>
GtkGridView
gtk_grid_view_new
gtk_grid_view_set_model
gtk_grid_view_get_model
gtk_grid_view_set_max_columns
gtk_grid_view_get_max_columns
gtk_grid_view_set_min_columns
gtk_grid_view_get_min_columns
<SUBSECTION Standard>
GTK_GRID_VIEW
GTK_GRID_VIEW_CLASS
GTK_GRID_VIEW_GET_CLASS
GTK_IS_GRID_VIEW
GTK_IS_GRID_VIEW_CLASS
GTK_TYPE_GRID_VIEW
<SUBSECTION Private>
gtk_grid_view_get_type
</SECTION>
<SECTION>
<FILE>gtkbuildable</FILE>
GtkBuildable
@@ -1286,6 +1430,32 @@ GTK_TYPE_FILE_FILTER
gtk_file_filter_get_type
</SECTION>
<SECTION>
<FILE>gtkdirectorylist</FILE>
<TITLE>GtkDirectoryList</TITLE>
GtkDirectoryList
gtk_directory_list_new
gtk_directory_list_get_attributes
gtk_directory_list_set_attributes
gtk_directory_list_get_file
gtk_directory_list_set_file
gtk_directory_list_get_io_priority
gtk_directory_list_set_io_priority
gtk_directory_list_is_loading
gtk_directory_list_get_error
<SUBSECTION Standard>
GTK_DIRECTORY_LIST
GTK_IS_DIRECTORY_LIST
GTK_TYPE_DIRECTORY_LIST
GTK_DIRECTORY_LIST_CLASS
GTK_IS_DIRECTORY_LIST_CLASS
GTK_DIRECTORY_LIST_GET_CLASS
<SUBSECTION Private>
gtk_directory_list_get_type
</SECTION>
<SECTION>
<FILE>gtkspinbutton</FILE>
<SECTION>
<FILE>gtkfilterlistmodel</FILE>
<TITLE>GtkFilterListModel</TITLE>
@@ -1683,8 +1853,8 @@ gtk_label_set_yalign
gtk_label_set_ellipsize
gtk_label_set_width_chars
gtk_label_set_max_width_chars
gtk_label_set_line_wrap
gtk_label_set_line_wrap_mode
gtk_label_set_wrap
gtk_label_set_wrap_mode
gtk_label_set_lines
gtk_label_get_layout_offsets
gtk_label_get_mnemonic_keyval
@@ -1704,8 +1874,8 @@ gtk_label_get_width_chars
gtk_label_get_max_width_chars
gtk_label_get_label
gtk_label_get_layout
gtk_label_get_line_wrap
gtk_label_get_line_wrap_mode
gtk_label_get_wrap
gtk_label_get_wrap_mode
gtk_label_get_lines
gtk_label_get_mnemonic_widget
gtk_label_get_selection_bounds
@@ -1786,6 +1956,8 @@ gtk_map_list_model_get_type
GtkMenu
gtk_menu_new
gtk_menu_new_from_model
GtkPopoverMenuFlags
gtk_menu_new_from_model_full
gtk_menu_reorder_child
gtk_menu_popup_at_rect
gtk_menu_popup_at_widget
@@ -1865,6 +2037,7 @@ gtk_menu_button_set_relief
gtk_menu_button_get_relief
gtk_menu_button_popup
gtk_menu_button_popdown
gtk_menu_button_set_create_popup_func
<SUBSECTION Standard>
GTK_TYPE_MENU_BUTTON
GTK_MENU_BUTTON
@@ -3042,7 +3215,7 @@ gtk_text_view_get_line_at_y
gtk_text_view_get_line_yrange
gtk_text_view_get_iter_at_location
gtk_text_view_get_iter_at_position
gtk_text_view_buffer_to_surface_coords
gtk_text_view_buffer_to_window_coords
gtk_text_view_window_to_buffer_coords
gtk_text_view_set_border_window_size
gtk_text_view_get_border_window_size
@@ -3057,8 +3230,10 @@ GtkTextChildAnchor
gtk_text_child_anchor_new
gtk_text_child_anchor_get_widgets
gtk_text_child_anchor_get_deleted
gtk_text_view_add_child_in_window
gtk_text_view_move_child
gtk_text_view_get_gutter
gtk_text_view_set_gutter
gtk_text_view_add_overlay
gtk_text_view_move_overlay
gtk_text_view_set_wrap_mode
gtk_text_view_get_wrap_mode
gtk_text_view_set_editable
@@ -3423,6 +3598,26 @@ gtk_tree_list_model_get_type
gtk_tree_list_row_get_type
</SECTION>
<SECTION>
<FILE>gtktreeexpander</FILE>
<TITLE>GtkTreeExpander</TITLE>
gtk_tree_expander_new
gtk_tree_expander_get_child
gtk_tree_expander_set_child
gtk_tree_expander_get_item
gtk_tree_expander_get_list_row
gtk_tree_expander_set_list_row
<SUBSECTION Standard>
GTK_TREE_EXPANDER
GTK_IS_TREE_EXPANDER
GTK_TYPE_TREE_EXPANDER
GTK_TREE_EXPANDER_CLASS
GTK_IS_TREE_EXPANDER_CLASS
GTK_TREE_EXPANDER_GET_CLASS
<SUBSECTION Private>
gtk_tree_expander_get_type
</SECTION>
<SECTION>
<FILE>gtktreemodel</FILE>
<TITLE>GtkTreeModel</TITLE>
@@ -4432,7 +4627,6 @@ gtk_widget_realize
gtk_widget_unrealize
gtk_widget_queue_draw
gtk_widget_queue_resize
gtk_widget_queue_resize_no_redraw
gtk_widget_queue_allocate
gtk_widget_get_frame_clock
gtk_widget_get_scale_factor
@@ -4511,6 +4705,7 @@ gtk_widget_get_allocation
gtk_widget_get_allocated_baseline
gtk_widget_get_width
gtk_widget_get_height
gtk_widget_get_size
gtk_widget_compute_bounds
gtk_widget_compute_transform
gtk_widget_compute_point
@@ -4549,11 +4744,6 @@ gtk_widget_get_opacity
gtk_widget_set_opacity
gtk_widget_get_overflow
gtk_widget_set_overflow
gtk_widget_insert_action_group
gtk_widget_list_action_prefixes
gtk_widget_get_action_group
gtk_widget_activate_action
gtk_widget_activate_default
gtk_widget_measure
gtk_widget_snapshot_child
gtk_widget_get_next_sibling
@@ -4609,7 +4799,6 @@ gtk_widget_get_vexpand
gtk_widget_set_vexpand
gtk_widget_get_vexpand_set
gtk_widget_set_vexpand_set
gtk_widget_queue_compute_expand
gtk_widget_compute_expand
<SUBSECTION Templates>
@@ -4630,6 +4819,17 @@ gtk_widget_class_set_connect_func
gtk_widget_observe_children
gtk_widget_observe_controllers
<SUBSECTION Actions>
gtk_widget_insert_action_group
gtk_widget_activate_action
gtk_widget_activate_action_variant
gtk_widget_activate_default
GtkWidgetActionActivateFunc
gtk_widget_class_install_action
gtk_widget_class_install_property_action
gtk_widget_class_query_action
gtk_widget_action_set_enabled
<SUBSECTION Standard>
GTK_WIDGET
GTK_IS_WIDGET
@@ -5196,13 +5396,16 @@ GtkBindingSet
GtkBindingEntry
GtkBindingSignal
GtkBindingArg
gtk_binding_entry_add_signall
gtk_binding_set_new
gtk_binding_set_by_class
gtk_binding_set_find
gtk_bindings_activate
gtk_bindings_activate_event
gtk_binding_set_activate
gtk_binding_entry_add_action
gtk_binding_entry_add_action_variant
GtkBindingCallback
gtk_binding_entry_add_callback
gtk_binding_entry_add_signal
gtk_binding_entry_add_signal_from_string
gtk_binding_entry_skip
@@ -6696,6 +6899,8 @@ gtk_event_controller_key_forward
gtk_event_controller_key_get_group
gtk_event_controller_key_get_focus_origin
gtk_event_controller_key_get_focus_target
gtk_event_controller_key_contains_focus
gtk_event_controller_key_is_focus
<SUBSECTION Standard>
GTK_TYPE_EVENT_CONTROLLER_KEY
@@ -6734,6 +6939,8 @@ gtk_gesture_drag_get_type
<TITLE>GtkGestureLongPress</TITLE>
GtkGestureLongPress
gtk_gesture_long_press_new
gtk_gesture_long_press_set_delay_factor
gtk_gesture_long_press_get_delay_factor
<SUBSECTION Standard>
GTK_TYPE_GESTURE_LONG_PRESS
@@ -7282,3 +7489,87 @@ gtk_grid_layout_get_type
GTK_TYPE_GRID_LAYOUT_CHILD
gtk_grid_layout_child_get_type
</SECTION>
<SECTION>
<FILE>gtkconstraint</FILE>
GtkConstraint
GtkConstraintTarget
gtk_constraint_new
gtk_constraint_new_constant
gtk_constraint_get_target
GtkConstraintAttribute
gtk_constraint_get_target_attribute
GtkConstraintRelation
gtk_constraint_get_relation
gtk_constraint_get_source
gtk_constraint_get_source_attribute
gtk_constraint_get_multiplier
gtk_constraint_get_constant
GtkConstraintStrength
gtk_constraint_get_strength
gtk_constraint_is_required
gtk_constraint_is_attached
gtk_constraint_is_constant
<SUBSECTION Standard>
GTK_TYPE_CONSTRAINT
gtk_constraint_get_type
GTK_TYPE_CONSTRAINT_TARGET
gtk_constraint_target_get_type
</SECTION>
<SECTION>
<FILE>gtkconstraintlayout</FILE>
GtkConstraintLayout
GtkConstraintLayoutChild
GtkConstraintVflParserError
gtk_constraint_layout_new
<SUBSECTION Constraints>
gtk_constraint_layout_add_constraint
gtk_constraint_layout_remove_constraint
gtk_constraint_layout_remove_all_constraints
<SUBSECTION Guides>
gtk_constraint_layout_add_guide
gtk_constraint_layout_remove_guide
<SUBSECTION VFL>
gtk_constraint_layout_add_constraints_from_description
gtk_constraint_layout_add_constraints_from_descriptionv
<SUBSECTION>
gtk_constraint_layout_observe_constraints
gtk_constraint_layout_observe_guides
<SUBSECTION Standard>
GTK_TYPE_CONSTRAINT_LAYOUT
gtk_constraint_layout_get_type
GTK_TYPE_CONSTRAINT_LAYOUT_CHILD
gtk_constraint_layout_child_get_type
GTK_CONSTRAINT_VFL_PARSER_ERROR
gtk_constraint_vfl_parser_error_quark
</SECTION>
<SECTION>
<FILE>gtkconstraintguide</FILE>
GtkConstraintGuide
gtk_constraint_guide_new
gtk_constraint_guide_set_name
gtk_constraint_guide_get_name
gtk_constraint_guide_set_strength
gtk_constraint_guide_get_strength
gtk_constraint_guide_set_min_size
gtk_constraint_guide_get_min_size
gtk_constraint_guide_set_nat_size
gtk_constraint_guide_get_nat_size
gtk_constraint_guide_set_max_size
gtk_constraint_guide_get_max_size
<SUBSECTION Standard>
GTK_TYPE_CONSTRAINT_GUIDE
gtk_constraint_guide_get_tyoe
</SECTION>

View File

@@ -49,7 +49,7 @@
files for icon themes.
</para>
<para>
It expects to be given the <replaceable>PATH</replaceable> to a icon theme
It expects to be given the <replaceable>PATH</replaceable> to an icon theme
directory containing an <filename>index.theme</filename>, e.g.
<filename>/usr/share/icons/hicolor</filename>, and writes a
<filename>icon-theme.cache</filename> containing cached information about

View File

@@ -1,3 +1,6 @@
#include <gtk/gtk.h>
#include <gtk/gtkunixprint.h>
gtk_about_dialog_get_type
gtk_accel_group_get_type
gtk_accel_label_get_type
@@ -46,6 +49,10 @@ gtk_color_chooser_dialog_get_type
gtk_color_chooser_widget_get_type
gtk_combo_box_get_type
gtk_combo_box_text_get_type
gtk_constraint_get_type
gtk_constraint_guide_get_type
gtk_constraint_layout_get_type
gtk_constraint_target_get_type
gtk_container_get_type
gtk_css_provider_get_type
gtk_dialog_get_type
@@ -116,6 +123,7 @@ gtk_menu_tool_button_get_type
gtk_message_dialog_get_type
gtk_model_button_get_type
gtk_mount_operation_get_type
gtk_native_get_type
gtk_notebook_get_type
gtk_notebook_page_get_type
gtk_orientable_get_type

View File

@@ -23,6 +23,13 @@ private_headers = [
'gtkcolorswatchprivate.h',
'gtkcomboboxprivate.h',
'gtkcontainerprivate.h',
'gtkconstraintexpressionprivate.h',
'gtkconstraintguideprivate.h',
'gtkconstraintlayoutprivate.h',
'gtkconstraintprivate.h',
'gtkconstraintsolverprivate.h',
'gtkconstrainttypesprivate.h',
'gtkconstraintvflparserprivate.h',
'gtkcssanimatedstyleprivate.h',
'gtkcssanimationprivate.h',
'gtkcssarrayvalueprivate.h',
@@ -394,7 +401,7 @@ else
types_conf.set('DISABLE_ON_QUARTZ', '')
endif
if get_option('documentation')
if get_option('gtk_doc')
configure_file(input: 'version.xml.in', output: 'version.xml', configuration: version_conf)
configure_file(input: 'getting_started.xml.in', output: 'getting_started.xml', configuration: src_dir_conf)

View File

@@ -11,7 +11,10 @@ GTK is released under the GNU Library General Public License
applications. GTK has a C-based object-oriented architecture that
allows for maximum flexibility. Bindings for many other languages have
been written, including C++, Objective-C, Guile/Scheme, Perl, Python,
TOM, Ada95, Free Pascal, and Eiffel.
TOM, Ada95, Free Pascal, and Eiffel. The GTK library itself contains
<firstterm>widgets</firstterm>, that is, GUI components such as GtkButton
or GtkTextView.
</para>
<para>
GTK depends on the following libraries:
@@ -105,14 +108,6 @@ and rendering it using different rendering APIs. GSK provides renderers
for OpenGL, Vulkan and cairo.
</para></listitem>
</varlistentry>
<varlistentry>
<term>GTK</term>
<listitem><para>
The GTK library itself contains <firstterm>widgets</firstterm>,
that is, GUI components such as GtkButton or GtkTextView.
</para></listitem>
</varlistentry>
</variablelist>
</para>
</partintro>

View File

@@ -1,4 +1,4 @@
if get_option('documentation')
if get_option('gtk_doc')
glib_prefix = dependency('glib-2.0').get_pkgconfig_variable('prefix')
glib_docpath = join_paths(glib_prefix, 'share', 'gtk-doc', 'html')

View File

@@ -1,97 +0,0 @@
HANDLING WIDGET STYLES
======================
A widget gets created with a default style.
The global default style can be affected by gtk_widget_set_default_style()
and can be queried by gtk_widget_get_default_style().
The initial style that is assigned to a widget as default style upon
creation can be affected by wrapping the widget's creation as follows:
gtk_widget_push_style (my_style);
widget = gtk_type_new (gtk_button_get_type ());
gtk_widget_pop_style ();
There are certain functions to affect widget styles after a widget's
creation:
gtk_widget_set_style ()
Save the default style and set a user style.
This will override a previously set user style or
previously set rc styles.
gtk_widget_reset_rc_styles ()
Descends through a widget hierarchy and sets the rc style
on all widgets that don't have a user style set.
gtk_widget_ensure_style ()
Ensure that the widget either has a user style set, or an rc lookup
has been performed.
gtk_rc_get_style ()
Return an rc style for a widget if there is one.
gtk_widget_set_name ()
Change widget name, and perform a new rc lookup if no user style
is set.
gtk_widget_realize ()
Besides realizing the widget this function will:
- perform an rc lookup if necessary,
- attach a widget's style.
gtk_widget_get_style ()
Return a widgets style, this function will perform an rc lookup
if necessary.
gtk_widget_set_parent ()
This function will perform rc lookups recursively for all widgets
that do not have a user style set.
gtk_style_copy ()
This function can be used to copy a widget's style.
The style can subsequently be changed (e.g., by modifications to the
red/green/blue values of a certain color) and then be applied to the
widget via gtk_widget_set_style().
GtkWidget::style_set
This signal will be emitted for a widget once its style changes with
an additional argument previous_style which will hold the widget->style
value from a previous emission.
The initial emission of this signal is guaranteed to happen prior
to any GtkWidget::size_request emission, and will have the previous_style
argument set to NULL.
The GtkWidgetClass implements a default handler for this signal that
will set the widget's window's background of widgets that provide their
own windows according to the new style.
Derived widgets need to override this default handler, if:
- their size requisition depends on the current style.
(e.g., on the style's fonts)
- they set the background of widget->window to something other than.
style->bg. (e.g., GtkListItem)
- the widget provides windows other than widget->window.
- the widget has any other stored dependencies on the style.
Flag indications:
!GTK_RC_STYLE && !GTK_USER_STYLE:
The widget has its default style set, no rc lookup has been
performed, the widget has not been size requested yet and is
therefore not yet realized.
GTK_USER_STYLE:
GTK_RC_STYLE is not set.
The widget has a user style assigned, and its default style has been
saved.
GTK_RC_STYLE:
GTK_USER_STYLE is not set.
If the widget has a saved default style, it has been assigned an
rc style. If the widget does not have a saved default style, it still
has its default style but an rc lookup has already been performed.
- Tim Janik <timj@gimp.org>
1998/02/27

View File

@@ -1,4 +1,4 @@
if x11_enabled and get_option('documentation')
if x11_enabled and get_option('gtk_doc')
doc_shooter_sources = [
'shadow.c',
'shooter.c',

View File

@@ -6,7 +6,7 @@ anyone who hopes to work with the code in the future.
HOW THE GTKTREEVIEW CALCULATES SIZE:
====================================
When the view is given a new model, the first thing it does is walk
through the model at the top level, creating an GtkRBNode for each
through the model at the top level, creating a GtkRBNode for each
element of the model. Each node has a height of 0. The RBTree is kept
updated as the models structure changes. Additionally, the user can
expand, collapse, and select rows at this stage. The RBTree is accurate

View File

@@ -1,836 +0,0 @@
This file is some notes about how different widgets are drawn.
=============
GtkMenu
=============
+----------------------------------------------------------------------------+
| A |
| +------------------------------------------------------------------------+ |
| |############################# C ########################################| |
| |# D #| |
| |# +-------------------------------------------------------------------+#| |
| |# | |#| |
| |# | |#| |
| |# | |#| |
| |# | Item 1 |#| |
| |# | |#| |
| |# | |#| |
| |# | |#| |
| |# | |#| |
| |# | |#| |
| |# +-------------------------------------------------------------------+#| |
| |# +-------------------------------------------------------------------+#| |
| |# | |#| |
| |# | |#| |
|A|B | |B|A|
| |# | Item 2 |#| |
| |# | |#| |
| |# | |#| |
| |# | |#| |
| |# | |#| |
| |# | |#| |
| |# +-------------------------------------------------------------------+#| |
| |# [...] #| |
| |# +-------------------------------------------------------------------+#| |
| |# | |#| |
| |# | |#| |
| |# | |#| |
| |# | Item n |#| |
| |# | |#| |
| |# | |#| |
| |# | |#| |
| |# | |#| |
| |# | |#| |
| |# +-------------------------------------------------------------------+#| |
| |# D #| |
| |############################# C ########################################| |
| +------------------------------------------------------------------------| |
| A |
+----------------------------------------------------------------------------+
A: GtkContainer::border_width
B: xthickness
C: ythickness
D: vertical_padding
=============
GtkMenuItem
=============
+----------------------------------------------------------------------------+
| A |
| +------------------------------------------------------------------------+ |
| |############################# C ########################################| |
| |#+-+------------+--+-------------------------------+--+-------------+-+#| |
| |#| |\\\\\\\\\\\\| | /|\ |**| | |#| |
| |#| |<------E------>| | |**| G | |#| |
| |#| |\\\\\\\\\\\\| | | |**| | |#| |
| |#| |\\\\\\\\\\\\| | | |**| >> | |#| |
| |#| |\\\\\\\\\\\\| | | |**| >>>> | |#| |
| |#| |\\\\\\\\\\\\| | | |**| >>>>>> | |#| |
|A|B|D|\\\\\\\\\\\\| F| Child G |*H| >>>>>>>> |D|B|A|
| |#| |\\\\\\\\\\\\| | | |**| >>>>>> | |#| |
| |#| |\\\\\\\\\\\\| | | |**| >>>> | |#| |
| |#| |\\\\\\\\\\\\| | | |**| >> | |#| |
| |#| |\\\\\\\\\\\\| | | |**| | |#| |
| |#| |\\\\\\\\\\\\| | | |**| | |#| |
| |#| |\\\\\\\\\\\\| | \|/ |**| | |#| |
| |#+-+------------+--+-------------------------------+--+-------------+-+#| |
| |############################# C ########################################| |
| +------------------------------------------------------------------------+ |
| A |
+----------------------------------------------------------------------------+
A: GtkContainer:border_width
B: xthickness
C: ythickness
D: horizontal_padding
E: toggle_size
F: toggle_spacing
G: Requested height of child (also used for width of arrow
H: arrow_spacing spacing (when the item has a non-vertical submenu)
=============
GtkOptionMenu:
=============
Geometry parameters
Style properties
GtkWidget::interior_focus = TRUE
GtkWidget::focus_width = 1
GtkWidget::focus_padding = 0
GtkOptionMenu::indicator_size = { 7, 13 }
GtkOptionMenu::indicator_spacing = { 7, 5, 2, 2 }
Properties
GtkContainer::border_width = 0
#defines
CHILD_LEFT_SPACING = 5
CHILD_RIGHT_SPACING = 1
CHILD_TOP_SPACING = 1
CHILD_BOTTOM_SPACING = 1
I) interior_focus = TRUE
+--------------------------------------------------+
+ A |
| +----------------------------------------------+ |
| |\\\\\\\\\\\\\\\\\\\\ H ///////////////////////| |
| |\+------------------------------------------+/| |
| |\| C |/| |
| |\| +------------------------------+ |/| |
| |\| |################ D ###########| L |/| |
| |\| |#+--------------------------+#| |/| |
| |\| |#| K |#| |/| |
| |\| |#| +----------------------+ |#| +-----+ |/| |
| |\| |#| | | |#| | /#\ | |/| |
| |\| |#| | | |#| | === | |/| |
|A|B|C|D|E| Child |F|D|G| IxJ |O|B|A|
| |/| |#| | | |#| | === | |\| |
| |/| |#| | | |#| | \#/ | |\| |
| |/| |#| +----------------------+ |#| +-----+ |\| |
| |/| |#| M |#| |\| |
| |/| |#+---------------------------#| |\| |
| |/| |################ D ###########| N |\| |
| |/| +------------------------------+ |\| |
| |/| C |\| |
| |/+------------------------------------------+\| |
| |//////////////////// H \\\\\\\\\\\\\\\\\\\\\\\| |
| +----------------------------------------------+ |
| A |
+--------------------------------------------------+
A: GtkContainer::border_width
B: xthickness
C: GtkWidget::focus_pad
D: GtkWidget::focus_width
E: CHILD_LEFT_SPACING
F: CHILD_RIGHT_SPACING
G: GtkOptionMenu::indicator_spacing::left
H: ythickness
I: GtkOptionMenu::indicator_size::width
J: GtkOptionMenu::indicator_size::height
K: CHILD_TOP_SPACING
L: GtkOptionMenu::indicator_spacing::top + GtkWidget::focus_width + GtkWidget::focus_pad + CHILD_TOP_SPACING
M: CHILD_BOTTOM_SPACING
N: GtkOptionMenu::indicator_spacing::bottom + GtkWidget::focus_width + GtkWidget::focus_pad + CHILD_BOTTOM_SPACING
O: GtkOptionMenu::indicator_spacing::right
II) interior_focus = FALSE
+--------------------------------------------------+
+ A |
| +----------------------------------------------+ |
| |#################### B #######################| |
| |#+------------------------------------------+#| |
| |#| C |#| |
| |#| +--------------------------------------+ |#| |
| |#| |\\\\\\\\\\\\\\\\ H ///////////////////| |#| |
| |#| |\+----------------------------------+/| |#| |
| |#| |\| K L |/| |#| |
| |#| |\| +----------------------+ +-----+ |/| |#| |
| |#| |\| | | | /#\ | |/| |#| |
| |#| |\| | | | === | |/| |#| |
|A|B|C|D|E| Child |F| IxJ |G|D|C|B|A|
| |#| |/| | | | === | |\| |#| |
| |#| |/| | | | \#/ | |\| |#| |
| |#| |/| +----------------------+ +-----+ |\| |#| |
| |#| |/| M N |\| |#| |
| |#| |/+----------------------------------+\| |#| |
| |#| |//////////////// H \\\\\\\\\\\\\\\\\\\| |#| |
| |#| +--------------------------------------+ |#| |
| |#| C |#| |
| |#+------------------------------------------+#| |
| |#################### B #######################| |
| +----------------------------------------------+ |
| A |
+--------------------------------------------------+
A: GtkContainer::border_width
B: GtkWidget::focus_width
C: GtkWidget::focus_padding
D: xthickness
E: CHILD_LEFT_SPACING
F: CHILD_RIGHT_SPACING + GtkOptionMenu::indicator_spacing::left
G: GtkOptionMenu::indicator_spacing::right
H: ythickness
I: GtkOptionMenu::indicator_size::width
J: GtkOptionMenu::indicator_size::height
K: CHILD_TOP_SPACING
L: CHILD_TOP_SPACING + GtkOptionMenu::indicator_spacing::top
M: CHILD_BOTTOM_SPACING
N: CHILD_BOTTOM_SPACING + GtkOptionMenu::indicator_spacing::bottom
III) interior_focus = FALSE, !HAVE_FOCUS
+--------------------------------------------------+
+ A |
| +----------------------------------------------+ |
| |\\\\\\\\\\\\\\\\\\\\ H ///////////////////////| |
| |\+------------------------------------------+/| |
| |\| |/| |
| |\| |/| |
| |\| |/| |
| |\| |/| |
| |\| K L |/| |
| |\| +----------------------+ +-----+ |/| |
| |\| | | | /#\ | |/| |
| |\| | | | === | |/| |
|A|D| E| Child |F| IxJ |G |D|A|
| |/| | | | === | |\| |
| |/| | | | \#/ | |\| |
| |/| +----------------------+ +-----+ |\| |
| |/| M N |\| |
| |/| |\| |
| |/| |\| |
| |/| |\| |
| |/| |\| |
| |/+------------------------------------------+\| |
| |//////////////////// H \\\\\\\\\\\\\\\\\\\\\\\| |
| +----------------------------------------------+ |
| A |
+--------------------------------------------------+
A: GtkContainer::border_width
B: GtkWidget::focus_width
C: GtkWidget::focus_padding
D: xthickness
E: CHILD_LEFT_SPACING + GtkWidget::focus_width + GtkWidget::focus_padding
F: CHILD_RIGHT_SPACING + GtkOptionMenu::in+icator_spacing::left
G: GtkOptionMenu::indicator_spacing::right + GtkWidget::focus_width + GtkWidget::focus_padding
H: ythickness
I: GtkOptionMenu::indicator_size::width
J: GtkOptionMenu::indicator_size::height
K: CHILD_TOP_SPACING + GtkWidget::focus_width + GtkWidget::focus_padding
L: CHILD_TOP_SPACING + GtkOptionMenu::indicator_spacing::top + GtkWidget::focus_width + GtkWidget::focus_padding
M: CHILD_BOTTOM_SPACING + GtkWidget::focus_width + GtkWidget::focus_padding
N: CHILD_BOTTOM_SPACING + GtkOptionMenu::indicator_spacing::bottom + GtkWidget::focus_width + GtkWidget::focus_padding
=====================
GtkButton
=====================
NOTE: Due to a bug that is basically unfixable in a sufficiently compatible
NOTE: way, the button gives the space requested for focus_width and
NOTE: focus_padding to the child (in addition to the space requested by
NOTE: the child), if the button is !CAN_FOCUS.
Style properties
GtkWidget::interior_focus = TRUE
GtkWidget::focus_width = 1
GtkWidget::focus_padding = 0
GtkButton::default_border = { 1, 1, 1, 1 };
GtkButton::default_outside_border = { 0, 0, 0, 0 };
GtkButton::child_displacement_x = 0;
GtkButton::child_displacement_y = 0;
Properties
GtkContainer::border_width = 0
#defines
CHILD_SPACING 1
I) HAS_DEFAULT && (!GtkWidget::interior-focus || !HAVE_FOCUS)
+----------------------------------------------+
| A |
| +------------------------------------------+ |
| |@@@@@@@@@@@@@@@@@@@ I @@@@@@@@@@@@@@@@@@@@| |
| |@+--------------------------------------+@| |
| |@|\\\\\\\\\\\\\\\\\ J //////////////////|@| |
| |@|\+----------------------------------+/|@| |
| |@|\| E |/|@| |
| |@|\| +------------------------------+ |/|@| |
| |@|\| |############# F ##############| |/|@| |
| |@|\| |#+--------------------------+#| |/|@| |
| |@|\| |#| L |#| |/|@| |
| |@|\| |#| +----------------------+ |#| |/|@| |
| |@|\| |#| | | |#| |/|@| |
| |@|\| |#| | | |#| |/|@| |
|A|B|D|E|F|G| Child |M|F|E|D|C|A|
| |@|/| |#| | | |#| |\|@| |
| |@|/| |#| | | |#| |\|@| |
| |@|/| |#| +----------------------+ |#| |\|@| |
| |@|/| |#| N |#| |\|@| |
| |@|/| |#+--------------------------+#| |\|@| |
| |@|/| |############# F ##############| |\|@| |
| |@|/| +------------------------------+ |\|@| |
| |@|/| E |\|@| |
| |@|/+----------------------------------+\|@| |
| |@|///////////////// J \\\\\\\\\\\\\\\\\\|@| |
| |@+--------------------------------------+@| |
| |@@@@@@@@@@@@@@@@@@@ K @@@@@@@@@@@@@@@@@@@@| |
| +------------------------------------------+ |
| A |
+----------------------------------------------+
A: GtkContainer::border-width
B: GtkButton::default-border::left
C: GtkButton::default-border::right
D: xthickness
E: GtkWidget::focus-padding
F: GtkWidget::focus-line-width
G: CHILD_SPACING + (depressed ? GtkButton::child-displacement-x : 0)
I: GtkButton::default-border::top
J: ythickness
K: GtkButton::default-border::bottom
L: CHILD_SPACING + (depressed ? GtkButton::child-displacement-y : 0)
M: CHILD_SPACING - (depressed ? GtkButton::child-displacement-x : 0)
N: CHILD_SPACING - (depressed ? GtkButton::child-displacement-y : 0)
II) !HAS_DEFAULT && (!GtkWidget::interior-focus || !HAVE_FOCUS)
+----------------------------------------------+
| |
| I |
| |
| +--------------------------------------+ |
| |\\\\\\\\\\\\\\\\\ J //////////////////| |
| |\+----------------------------------+/| |
| |\| E |/| |
| |\| +------------------------------+ |/| |
| |\| |############# F ##############| |/| |
| |\| |#+--------------------------+#| |/| |
| |\| |#| L |#| |/| |
| |\| |#| +----------------------+ |#| |/| |
| |\| |#| | | |#| |/| |
| |\| |#| | | |#| |/| |
| B |D|E|F|G| Child |M|F|E|D| C |
| |/| |#| | | |#| |\| |
| |/| |#| | | |#| |\| |
| |/| |#| +----------------------+ |#| |\| |
| |/| |#| N |#| |\| |
| |/| |#+--------------------------+#| |\| |
| |/| |############# F ##############| |\| |
| |/| +------------------------------+ |\| |
| |/| E |\| |
| |/+----------------------------------+\| |
| |///////////////// J \\\\\\\\\\\\\\\\\\| |
| +--------------------------------------+ |
| |
| K |
| |
+----------------------------------------------+
a) CAN_DEFAULT
B: GtkContainer::border-width + GtkButton::default-outside-border::left
C: GtkContainer::border-width + GtkButton::default-outside-border::right
D: xthickness
E: GtkWidget::focus-padding
F: GtkWidget::focus-line-width
G: CHILD_SPACING + (depressed ? GtkButton::child-displacement-x : 0) +
(GtkButton::default-outside-border - GtkButton::default-outside-border)::left
I: GtkContainer::border-width + GtkButton::default-outside-border::top
J: ythickness
K: GtkContainer::border-width + GtkButton::default-outside-border::bottom
L: CHILD_SPACING + (depressed ? GtkButton::child-displacement-y : 0) +
(GtkButton::default-outside-border - GtkButton::default-outside-border)::top
M: CHILD_SPACING - (depressed ? GtkButton::child-displacement-x : 0) +
(GtkButton::default-outside-border - GtkButton::default-outside-border)::right
N: CHILD_SPACING - (depressed ? GtkButton::child-displacement-y : 0) +
(GtkButton::default-outside-border - GtkButton::default-outside-border)::bottom
b) !CAN_DEFAULT
B: GtkContainer::border-width
C: GtkContainer::border-width
D: xthickness
E: GtkWidget::focus-padding
F: GtkWidget::focus-line-width
G: CHILD_SPACING + (depressed ? GtkButton::child-displacement-x : 0)
I: GtkContainer::border-width
J: ythickness
K: GtkContainer::border-width
L: CHILD_SPACING + (depressed ? GtkButton::child-displacement-y : 0)
M: CHILD_SPACING - (depressed ? GtkButton::child-displacement-x : 0)
N: CHILD_SPACING - (depressed ? GtkButton::child-displacement-y : 0)
III) HAS_DEFAULT && (GtkWidget::interior-focus && HAVE_FOCUS)
+----------------------------------------------+
| A |
| +------------------------------------------+ |
| |@@@@@@@@@@@@@@@@@@@ I @@@@@@@@@@@@@@@@@@@@| |
| |@+--------------------------------------+@| |
| |@|################# F ##################|@| |
| |@|#+----------------------------------+#|@| |
| |@|#| E |#|@| |
| |@|#| +------------------------------+ |#|@| |
| |@|#| |\\\\\\\\\\\\\ J //////////////| |#|@| |
| |@|#| |\+--------------------------+/| |#|@| |
| |@|#| |\| L |/| |#|@| |
| |@|#| |\| +----------------------+ |/| |#|@| |
| |@|#| |\| | | |/| |#|@| |
| |@|#| |\| | | |/| |#|@| |
|A|B|F|E|D|G| Child |M|D|E|F|C|A|
| |@|#| |/| | | |\| |#|@| |
| |@|#| |/| | | |\| |#|@| |
| |@|#| |/| +----------------------+ |\| |#|@| |
| |@|#| |/| N |\| |#|@| |
| |@|#| |/+--------------------------+\| |#|@| |
| |@|#| |///////////// J \\\\\\\\\\\\\\| |#|@| |
| |@|#| +------------------------------+ |#|@| |
| |@|#| E |#|@| |
| |@|#+----------------------------------+#|@| |
| |@|################# F ##################|@| |
| |@+--------------------------------------+@| |
| |@@@@@@@@@@@@@@@@@@@ K @@@@@@@@@@@@@@@@@@@@| |
| +------------------------------------------+ |
| A |
+----------------------------------------------+
A: GtkContainer::border-width
B: GtkButton::default-border::left
C: GtkButton::default-border::right
D: xthickness
E: GtkWidget::focus-padding
F: GtkWidget::focus-line-width
G: CHILD_SPACING + (depressed ? GtkButton::child-displacement-x : 0)
I: GtkButton::default-border::top
J: ythickness
K: GtkButton::default-border::bottom
L: CHILD_SPACING + (depressed ? GtkButton::child-displacement-y : 0)
M: CHILD_SPACING - (depressed ? GtkButton::child-displacement-x : 0)
N: CHILD_SPACING - (depressed ? GtkButton::child-displacement-y : 0)
IV) !HAS_DEFAULT && (GtkWidget::interior-focus && HAVE_FOCUS)
+----------------------------------------------+
| |
| I |
| |
| +--------------------------------------+ |
| |################# J ##################| |
| |#+----------------------------------+#| |
| |#| E |#| |
| |#| +------------------------------+ |#| |
| |#| |\\\\\\\\\\\\\ F //////////////| |#| |
| |#| |\+--------------------------+/| |#| |
| |#| |\| L |/| |#| |
| |#| |\| +----------------------+ |/| |#| |
| |#| |\| | | |/| |#| |
| |#| |\| | | |/| |#| |
| B |D|E|F|G| Child |M|F|E|D| C |
| |#| |/| | | |\| |#| |
| |#| |/| | | |\| |#| |
| |#| |/| +----------------------+ |\| |#| |
| |#| |/| N |\| |#| |
| |#| |/+--------------------------+\| |#| |
| |#| |///////////// F \\\\\\\\\\\\\\| |#| |
| |#| +------------------------------+ |#| |
| |#| E |#| |
| |#+----------------------------------+#| |
| |################# J ##################| |
| +--------------------------------------+ |
| |
| K |
| |
+----------------------------------------------+
a) CAN_DEFAULT
B: GtkContainer::border-width + GtkButton::default-outside-border::left
C: GtkContainer::border-width + GtkButton::default-outside-border::right
D: xthickness
E: GtkWidget::focus-padding
F: GtkWidget::focus-line-width
G: CHILD_SPACING + (depressed ? GtkButton::child-displacement-x : 0) +
(GtkButton::default-outside-border - GtkButton::default-outside-border)::left
I: GtkContainer::border-width + GtkButton::default-outside-border::top
J: ythickness
K: GtkContainer::border-width + GtkButton::default-outside-border::bottom
L: CHILD_SPACING + (depressed ? GtkButton::child-displacement-y : 0) +
(GtkButton::default-outside-border - GtkButton::default-outside-border)::top
M: CHILD_SPACING - (depressed ? GtkButton::child-displacement-x : 0) +
(GtkButton::default-outside-border - GtkButton::default-outside-border)::right
N: CHILD_SPACING - (depressed ? GtkButton::child-displacement-y : 0) +
(GtkButton::default-outside-border - GtkButton::default-outside-border)::bottom
b) !CAN_DEFAULT
B: GtkContainer::border-width
C: GtkContainer::border-width
D: xthickness
E: GtkWidget::focus-padding
F: GtkWidget::focus-line-width
G: CHILD_SPACING + (depressed ? GtkButton::child-displacement-x : 0)
I: GtkContainer::border-width
J: ythickness
K: GtkContainer::border-width
L: CHILD_SPACING + (depressed ? GtkButton::child-displacement-y : 0)
M: CHILD_SPACING - (depressed ? GtkButton::child-displacement-x : 0)
N: CHILD_SPACING - (depressed ? GtkButton::child-displacement-y : 0)
======================
GtkCheckButton
======================
Note: This is the draw_indicator=TRUE case; draw_indicator=FALSE
is like GtkButton)
Style properties
GtkWidget::interior_focus = TRUE
GtkWidget::focus_width = 1
GtkWidget::focus_padding = 0
GtkButton::indicator-size = 13
GtkButton::indicator-spacing = 2
Properties
GtkContainer::border_width = 0
#defines
CHILD_SPACING 1
interior_focus
+-------------------------------------------+
| F |
| G +------------------------+ |
| |########### D ##########| |
| +------------+ |#+--------------------+#| |
| | | |#| E |#| |
| | | |#| +----------------+ |#| |
| | | |#| | | |#| |
|A| BxB |C|D|E| Child |E|#|F|
| | | |#| | | |#| |
| | | |#| +----------------+ |#| |
| | | |#| E |#| |
| +------------+ |#+--------------------+#| |
| |########### D ##########| |
| G +------------------------+ |
| F |
+-------------------------------------------+
A: GtkContainer::border-width + GtkCheckButton::indicator-spacing
B: GtkCheckButton::indicator-size
C: 2 * GtkCheckButton::indicator-spacing
D: GtkWidget::focus-line-width
E: GtkWidget::focus-padding
F: GtkContainer::border-width
G: GtkConainer::border-width + GtkCheckButton::indicator-spacing
!interior_focus
+-------------------------------------------+
| A |
| +---------------------------------------+ |
| |################ D ####################| |
| |#+-----------------------------------+#| |
| |#| G E |#| |
| |#| +------------+ +---------------+ |#| |
| |#| | | | | |#| |
| |#| | | | | |#| |
|A|D|F| BxB |C | Child |E|D|A|
| |#| | | | | |#| |
| |#| | | | | |#| |
| |#| +------------+ +---------------+ |#| |
| |#| G E |#| |
| |#+-----------------------------------+#| |
| |################ D ####################| |
| +---------------------------------------+ |
| A |
+-------------------------------------------+
A: GtkContainer::border-width
B: GtkCheckButton::indicator-size
C: 2 * GtkCheckButton::indicator-spacing
D: GtkWidget::focus-line-width
E: GtkWidget::focus-padding
F: GtkWidget::focus-padding + GtkCheckButton::indicator-spacing
G: GtkWidget::focus-padding + GtkCheckButton::indicator-spacing
===============
GtkEntry
===============
Style properties
GtkWidget::interior_focus = TRUE
GtkWidget::focus_width = 1
GtkWidget::focus_padding = 0
Properties
GtkContainer::border_width = 0
#defines
INNER_BORDER 2
interior_focus
+--------------------------------------+
|\\\\\\\\\\\\\\\\\ B //////////////////|
|\+----------------------------------+/|
|\| D |/|
|\| +------------------------------+ |/|
|\| | | |/|
|\| | | |/|
|A|D| |D|A|
|\| | | |/|
|\| | | |/|
|\| +------------------------------+ |/|
|\| D |/|
|\+----------------------------------+/|
|///////////////// B \\\\\\\\\\\\\\\\\/|
+--------------------------------------+
A: xthickness
B: ythickness
D: INNER_BORDER
!interior_focus
+------------------------------------------+
|####################C#####################|
|#+--------------------------------------+#|
|#|\\\\\\\\\\\\\\\\\ B //////////////////|#|
|#|\+----------------------------------+/|#|
|#|\| D |/|#|
|#|\| +------------------------------+ |/|#|
|#|\| | | |/|#|
|#|\| | | |/|#|
|C|A|D| |D|A|C|
|#|\| | | |/|#|
|#|\| | | |/|#|
|#|\| +------------------------------+ |/|#|
|#|\| D |/|#|
|#|\+----------------------------------+/|#|
|#|///////////////// B \\\\\\\\\\\\\\\\\/|#|
|#+--------------------------------------+#|
|####################C#####################|
+------------------------------------------+
A: xthickness
B: ythickness
C: GtkWidget::focus-line-width
D: INNER_BORDER + (HAVE_FOCUS ? 0 : GtkWidget::focus-line-width
Note - effect here for !interior_focus is that bevel moves in
by focus-line-width when entry gains focus
===============
GtkExpander
===============
Style properties
GtkWidget::focus_line_width
GtkWidget::focus_padding
GtkExpander::expander_size
GtkExpander::expander_spacing
Properties
GtkContainer::border_width
GtkExpander::spacing
if (GTK_WIDGET_VISIBLE (bin->child) && interior_focus)
+-------------------------------------+
| A |
| +---------+-----------------------+ |
| | C |##########E############| |
| | +-----+ |#+-------------------+#| |
| | | | |#| F |#| |
| | | | |#| +---------------+ |#| |
|A|C| BxB |C|E|F| label_widget |F|E|A|
| | | | |#| +---------------+ |#| |
| | | | |#| F |#| |
| | +-----+ |#+-------------------+#| |
| | C |##########E############| |
| +---------+-----------------------+ |
| | D | |
| +---------------------------------+ |
| | | |
| | | |
| | | |
|A| bin->child |A|
| | | |
| | | |
| | | |
| +---------------------------------+ |
| A |
+-------------------------------------+
A: GtkContainer::border_width
B: GtkExpander::expander_size
C: GtkExpander::expander_spacing
D: GtkExpander::spacing
E: GtkWidget::focus_line_width
F: GtkWidget::focus_padding
if (GTK_WIDGET_VISIBLE (bin->child) && !interior_focus)
+-------------------------------------------+
| A |
| +---------------------------------------+ |
| |##################E####################| |
| |#+-----------------------------------+#| |
| |#| F |#| |
| |#| +---------+---------------------+ |#| |
| |#| | C | | |#| |
| |#| | +-----+ | | |#| |
|A|E|F|C| BxB |C| label_widget |F|E|A|
| |#| | +-----+ | | |#| |
| |#| | C | | |#| |
| |#| +---------+---------------------+ |#| |
| |#| F |#| |
| |#+-----------------------------------+#| |
| |##################E####################| |
| +---------------------------------------+ |
| | D | |
| +---------------------------------------+ |
| | | |
| | | |
| | | |
|A| bin->child |A|
| | | |
| | | |
| | | |
| +---------------------------------------+ |
| A |
+-------------------------------------------+
A: GtkContainer::border_width
B: GtkExpander::expander_size
C: GtkExpander::expander_spacing
D: GtkExpander::spacing
E: GtkWidget::focus_line_width
F: GtkWidget::focus_padding
if (!GTK_WIDGET_VISIBLE (bin->child) && interior_focus)
+-------------------------------------+
| A |
| +---------+-----------------------+ |
| | C |##########E############| |
| | +-----+ |#+-------------------+#| |
| | | | |#| F |#| |
| | | | |#| +---------------+ |#| |
|A|C| BxB |C|E|F| label_widget |F|E|A|
| | | | |#| +---------------+ |#| |
| | | | |#| F |#| |
| | +-----+ |#+-------------------+#| |
| | C |##########E############| |
| +---------+-----------------------+ |
| A |
+-------------------------------------+
A: GtkContainer::border_width
B: GtkExpander::expander_size
C: GtkExpander::expander_spacing
E: GtkWidget::focus_line_width
F: GtkWidget::focus_padding
if (!GTK_WIDGET_VISIBLE (bin->child) && !interior_focus)
+-------------------------------------------+
| A |
| +---------------------------------------+ |
| |##################E####################| |
| |#+-----------------------------------+#| |
| |#| F |#| |
| |#| +---------+---------------------+ |#| |
| |#| | C | | |#| |
| |#| | +-----+ | | |#| |
|A|E|F|C| BxB |C| label_widget |F|E|A|
| |#| | +-----+ | | |#| |
| |#| | C | | |#| |
| |#| +---------+---------------------+ |#| |
| |#| F |#| |
| |#+-----------------------------------+#| |
| |##################E####################| |
| +---------------------------------------+ |
| A |
+-------------------------------------------+
A: GtkContainer::border_width
B: GtkExpander::expander_size
C: GtkExpander::expander_spacing
E: GtkWidget::focus_line_width
F: GtkWidget::focus_padding

View File

@@ -1,500 +0,0 @@
Notes about the inner workings of the widget system of GTK
==========================================================
This file contains some notes as to how the widget system does
and should work. It consists of three parts:
I) A description of the meaning of the various flags
II) A list of invariants about the states of the widgets.
(Throughout this document, we refer to the states of the
widgets by referring to the flags for GtkWidget)
III) Some notes about the ways that a widget changes states
IV) A list of responsibilities of various widget signals when
the states change.
Any action necessary to maintain the invariants in II which is not
explicitly mentioned in IV), is the responsibility of the core GTK
code, which is roughly defined as:
gtkobject.c
gtkwidget.c
gtkcontainer.c
gtkmain.c
gtksignal.c
Section II is mostly of interest to those maintaining GTK, the
other sections may also be interesting to people writing
new widgets.
Main outline:
- Owen Taylor <owt1@cornell.edu>
1998/02/03
Flag descriptions:
- Tim Janik <timj@gimp.org>
1998/02/04
I. Flags
--------
GtkObject:
GTK_DESTROYED:
This flagged is set for a GtkObject right before its
destruction code is executed. Its main use is the
prevention of multiple destruction invocations.
GTK_FLOATING:
This flag reflects the fact that the holder of the
initial reference count is unknown. Refer to refcounting.txt
for further details.
GTK_RESERVED_1:
GTK_RESERVED_2:
Reserved flags.
GtkWidget, public flags:
GTK_TOPLEVEL:
Widgets without a real parent, as there are GtkWindows and
GtkMenus have this flag set throughout their lifetime.
Toplevel widgets always contain their own GdkSurface.
GTK_NO_WINDOW:
This flag is indicative for a widget that does not provide
its own GdkSurface. Visible action (e.g. drawing) is performed
on the parent's GdkSurface.
GTK_REALIZED:
Set by gtk_widget_realize, unset by gtk_widget_unrealize.
Relies on ((widget->parent && widget->parent->window)
|| GTK_WIDGET_TOPLEVEL (widget));
Means: widget has an associated GdkSurface (XWindow).
GTK_MAPPED:
Set by gtk_widget_map, unset by gtk_widget_unmap.
May only be set if GTK_WIDGET_REALIZED (widget).
Means: gdk_surface_show() has been called on the widgets window(s).
GTK_VISIBLE:
Set by gtk_widget_show.
Implies that a widget will be flagged GTK_MAPPED as soon as its
parent is mapped.
!GTK_VISIBLE:
Set by gtk_widget_hide.
Implies that a widget is not onscreen, therefore !GTK_MAPPED.
GTK_CHILD_VISIBLE
Set by gtk_widget_set_child_visible, and if FALSE indicates that
the widget should not be mapped even if the parent is mapped
and visible. Containers like GtkNotebook use this flag.
A private flag, not a public flag, so if you need to check
this flag, you should call gtk_widget_get_child_visible().
(Should be very rarely necessary.)
GTK_SENSITIVE:
Set and unset by gtk_widget_set_sensitive.
The sensitivity of a widget determines whether it will receive
certain events (e.g. button or key presses). One premise for
the widgets sensitivity is to have GTK_SENSITIVE set.
GTK_PARENT_SENSITIVE:
Set and unset by gtk_widget_set_sensitive operations on the
parents of the widget.
This is the second premise for the widgets sensitivity. Once
it has GTK_SENSITIVE and GTK_PARENT_SENSITIVE set, its state is
effectively sensitive. This is expressed (and can be examined) by
the GTK_WIDGET_IS_SENSITIVE macro.
GTK_CAN_FOCUS:
There are no directly corresponding functions for setting/unsetting
this flag, but it can be affected by the GtkWidget::has_focus argument
via gtk_widget_set_arg.
This flag determines whether a widget is able to handle focus grabs.
GTK_HAS_FOCUS:
This flag will be set by gtk_widget_grab_focus for widgets that also
have GTK_CAN_FOCUS set. The flag will be unset once another widget
grabs the focus.
GTK_CAN_DEFAULT:
GTK_HAS_DEFAULT:
These two flags are mostly equal in functionality to their *_FOCUS
counterparts, but for the default widget.
GTK_HAS_GRAB:
Set by gtk_grab_add, unset by gtk_grab_remove.
Means: widget is in the grab_widgets stack, and will be the preferred
one for receiving events other than ones of cosmetic value.
GTK_BASIC:
The GTK_BASIC flag is an attempt at making a distinction
between widgets that handle user input e.g. key/button presses
and those that don't. Subsequent parent<->child relation ships
of non `basic' widgets should be avoided. The checking for
this is currently not properly enforced in the code. For
example GtkButton is a non `basic' widget, that will therefore
disallow to act as a container for another GtkButton. Now the
gnit is, one can add a GtkHBox (which is a `basic' widget) to
the first button, and put the second into the box.
GTK_RESERVED_3:
GTK_RC_STYLE:
This flag indicates that its style has been looked up through
the rc mechanism. It does not imply that the widget actually
had a style defined through the rc mechanism.
GtkWidget, private flags:
GTK_USER_STYLE:
A widget is flagged to have a user style, once gtk_widget_set_style
has been invoked for it. The use of this flag is to tell widgets
which share a global user style from the ones which got a certain
style assign from outside the toolkit.
GTK_RESIZE_PENDING:
First, this is only valid for GtkContainers.
[some of the code should move to gtkcontainer.c therefore]
Relies on GTK_WIDGET_REALIZED(widget)
[this is not really enforced throughout the code, but should
be. it only requires a few checks for GTK_WIDGET_REALIZED and
minor changes to gtk_widget_unrealize, we can then remove the check
in gtk_widget_real_destroy]
Means: there is an idle handler waiting for the container to
resize it.
GTK_RESIZE_NEEDED:
Relies on GTK_WIDGET_REALIZED(widget)
[this is not really enforced throughout the code, but should
be. once this is done special checking in gtk_widget_real_destroy
can be avoided]
Means: a widget has been added to the resize_widgets list of
its _toplevel_ container (keep this in mind for GtkViewport).
Remark: this flag is also used internally by gtkwindow.c during
the evaluation of resizing worthy widgets.
GTK_LEAVE_PENDING:
A widget is flagged as such if there is a leave_notify event
pending for it. It will receive this event regardless of a grab
through another widget or its current sensitivity.
[this should be made relying on GTK_REALIZED]
GTK_HAS_SHAPE_MASK:
Set by gtk_widget_shape_combine_mask if a widget got a shape mask
assigned (making use of the X11 shaped window extension).
GTK_IN_REPARENT:
During the act of reparentation widgets which are already
realized and will be added to an already realized parent need
to have this flag set to prevent natural unrealization on the
process of getting unparented.
GTK_NEED_REQUEST:
This flag is set if the widget doesn't have an up to date
requisition. If this flag is set, we must actually emit ::size-request
when gtk_widget_size_request() is called. Otherwise, we can
simply widget->requisition. We keep track of this all the time
however, widgets with this flag set are only added to the resize
queue if they are viewable.
GTK_NEED_ALLOCATION:
This flag is set if the widget doesn't have an up to date
allocation. If this flag is set, we must actually emit ::size-allocate
when gtk_widget_size_allocate() is called, even if the new allocation
is the same as the current allocation.
Related Macros:
GTK_WIDGET_DRAWABLE:
This macro examines whether a widget is flagged as GTK_WIDGET_VISIBLE
and GTK_WIDGET_MAPPED.
Means: it _makes sense_ to draw in a widgets window.
GTK_WIDGET_IS_SENSITIVE:
This macro tells the real sensitivity state of a widget. It returns
whether both the widget and all its parents are in sensitive state.
II. Invariants:
---------------
This section describes various constraints on the states of
the widget:
In the following
A => B means if A is true, than B is true
A <=> B means A is true, if and only if B is true
(equivalent to A => B and A <= B)
1) GTK_WIDGET_DESTROYED (widget) => !GTK_WIDGET_REALIZED (widget)
=> !GTK_WIDGET_VISIBLE (widget)
[ The latter is not currently in place, but it should be ]
2) GTK_WIDGET_MAPPED (widget) => GTK_WIDGET_REALIZED (widget)
3) if GTK_WIDGET_TOPLEVEL (widget):
GTK_WIDGET_VISIBLE (widget) <=> GTK_WIDGET_MAPPED (widget)
4) if !GTK_WIDGET_TOPLEVEL (widget):
widget->parent && GTK_WIDGET_REALIZED (widget->parent) <=>
GTK_WIDGET_REALIZED (widget)
5) if !GTK_WIDGET_TOPLEVEL (widget):
GTK_WIDGET_MAPPED (widget) => GTK_WIDGET_VISIBLE (widget)
=> GTK_WIDGET_CHILD_VISIBLE (widget)
=> GTK_WIDGET_REALIZED (widget)
widget->parent && GTK_WIDGET_MAPPED (widget->parent) &&
GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_CHILD_VISIBLE
<=> GTK_WIDGET_MAPPED (widget)
Note:, the definition
[ GTK_WIDGET_DRAWABLE = GTK_WIDGET_VISIBLE && GTK_WIDGET_MAPPED
is made in gtkwidget.h, but by 3) and 5),
GTK_WIDGET_MAPPED => GTK_WIDGET_VISIBLE
]
6) GTK_REDRAW_PENDING => GTK_WIDGET_REALIZED
GTK_RESIZE_PENDING => "
GTK_LEAVE_PENDING => "
GTK_RESIZE_NEEDED => "
III. How states are changed:
----------------------------
How can the user control the state of a widget:
-----------------------------------------------
(In the following, set flag means set the flag, do appropriate
actions, and enforce above invariants)
gtk_widget_show:
if !GTK_DESTROYED sets GTK_VISIBLE
gtk_widget_hide:
if !GTK_VISIBLE for widget
gtk_widget_destroy:
sets GTK_DESTROYED
For a top-level widget
gtk_widget_realize:
if !GTK_DESTROYED sets GTK_REALIZED
- Calling gtk_widget_realize when the widget is not a descendant
of a toplevel is an ERROR.
gtk_container_add (container, widget) [ and container-specific variants ]
Sets widget->parent
gtk_container_remove (container, widget)
unsets widget->parent
gtk_widget_reparent (widget, new_parent)
Equivalent to removing widget from old parent and adding it to
the new parent, except that the widget will not be temporarily
unrealized if both the old parent and the new parent are realized.
gtk_widget_unrealize
gtk_widget_map
gtk_widget_unmap
These functions are not meant to be used by applications - they
are used only by GTK and widgets to enforce invariants on the
state.
When The X window corresponding to a GTK window is destroyed:
-------------------------------------------------------------
gtk_widget_destroy is called (as above).
IV. Responsibilities of widgets
--------------------------------
Adding to a container
---------------------
When a widget is added to a container, the container:
1) calls gtk_widget_set_parent_surface (widget, window) if
the widget is being added to something other than container->window
2) calls gtk_widget_set_parent (widget, container)
Removing from a container
-------------------------
When a widget is removed to a container, the container:
1) Calls gtk_widget_unparent (widget)
2) Queues a resize.
Notes:
gtk_widget_unparent unrealizes the widget except in the
special case GTK_IN_REPARENT is set.
At widget creation
------------------
Widgets are created in an unrealized state.
1) The widget should allocate and initialize needed data structures
The Realize signal
------------------
When a widget receives the "realize" signal it should:
NO_WINDOW widgets: (probably OK to use default handler)
1) set the realized flag
2) set widget->window
widget->window = gtk_widget_get_parent_surface (widget);
g_object_ref (widget->window);
3) attach the widget's style
widget->style = gtk_style_attach (widget->style, widget->window);
widget with window(s)
1) set the REALIZED flag
2) create windows with the parent obtained from
gtk_widget_get_parent_surface (widget);
3) attach the widget's style
4) set the background color for the new window based on the style
The Map signal
--------------
1) Set the MAPPED flag
2) If the widget has any windows, gdk_surface_show those windows
3) call gtk_widget_map for all child widgets that are
VISIBLE, CHILD_VISIBLE and !MAPPED. (A widget will only
be !CHILD_VISIBLE if the container set it that way, so
most containers will not have to check this.)
3) Do any other functions related to putting the widget onscreen.
(for instance, showing extra popup windows...)
The Unmap signal
----------------
When a widget receives the unmap signal, it must:
1) If the widget has a window, gdk_surface_hide that window,
2) If the widget does not have a window, unmap all child widgets
3) Do any other functions related to taking the widget offscreen
(for instance, removing popup windows...)
4) Unset GTK_MAPPED
The Unrealize signal
--------------------
When a widget receives the unrealize signal, it must
1) For any windows other than widget->window do:
gdk_surface_set_user_data (window, NULL);
gdk_surface_destroy (window);
2) Call the parent's unrealize handler
The Widget class unrealize handler will take care of unrealizing
all children if necessary. [should this be made consistent with
unmap???]
The Destroy Signal
------------------
Commentary:
The destroy signal probably shouldn't exist at all. A widget
should merely be unrealized and removed from its parent
when the user calls gtk_widget_destroy or a GDK_DESTROY event
is received. However, a large body of code depends on
getting a definitive signal when a widget goes away.
That could be put in the finalization step, but, especially
with language bindings, the cleanup step may need to refer
back to the widget. (To use gtk_widget_get_data, for instance)
If it does so via a pointer in a closure (natural for
Scheme, or Perl), then the finalization procedure will never
be called.
Also, if we made that the finalization step, we would have
to propagate the GDK_DESTROY event in any case, since it is
at that point at which user-visible actions need to be taken.
When a widget receives the destroy signal, it must:
1) If the widget "owns" any widgets other than its child
widgets, (for instance popup windows) it should
call gtk_widget_destroy () for them.
2) Call the parent class's destroy handler.
The "destroy" signal will only be received once. A widget
will never receive any other signals after the destroy
signal (but see the section on "Finalize" below)
The widget must handle calls to all publically accessible
functions in an innocuous manner even after a "destroy"
signal. (A widget can assume that it will not be realized
after a "destroy" signal is received, which may simplify
handling this requirement)
The Finalize Pseudo-signal
--------------------------
The finalize pseudo-signal is received after all references
to the widget have been removed. The finalize callback
cannot make any GTK calls with the widget as a parameter.
1) Free any memory allocated by the widget. (But _not_
the widget structure itself.
2) Call the parent class's finalize signal
A note on chaining "destroy" signals and finalize signals:
---------------------------------------------------------
This is done by code like:
if (GTK_OBJECT_CLASS (parent_class)->destroy)
(* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
It may not be completely obvious why this works. Note
that parent_class is a static variable on a per-class
basis. So say: we have
GtkFoo <- GtkBar <- GtkWidget <-GtkObject
And that Foo, Widget, and Object all have destructors, but
not Bar.
Then gtk_foo_destroy will call gtk_widget_destroy (because
it was not overridden in the Bar class structure) and
gtk_widget_destroy will call gtk_object_destroy because
the parent_class variable referenced by gtk_foo_destroy is the
static variable in gtkwidget.c: GtkObjectClass.

View File

@@ -98,7 +98,9 @@ _gdk_broadway_display_size_changed (GdkDisplay *display,
GdkBroadwaySurface *toplevel = l->data;
if (toplevel->maximized)
gdk_surface_move_resize (GDK_SURFACE (toplevel), 0, 0, msg->width, msg->height);
gdk_broadway_surface_move_resize (GDK_SURFACE (toplevel),
0, 0,
msg->width, msg->height);
}
}

View File

@@ -70,6 +70,12 @@ void _gdk_broadway_surface_grab_check_unmap (GdkSurface *surface,
gulong serial);
void gdk_broadway_surface_update_popups (GdkSurface *surface);
void gdk_broadway_surface_move_resize (GdkSurface *surface,
gint x,
gint y,
gint width,
gint height);
void _gdk_keymap_keys_changed (GdkDisplay *display);
gint _gdk_broadway_get_group_for_state (GdkDisplay *display,
GdkModifierType state);

View File

@@ -88,10 +88,10 @@ gdk_broadway_surface_finalize (GObject *object)
}
static gboolean
thaw_clock_cb (GdkFrameClock *clock)
thaw_updates_cb (GdkSurface *surface)
{
_gdk_frame_clock_thaw (clock);
g_object_unref (clock);
gdk_surface_thaw_updates (surface);
g_object_unref (surface);
return G_SOURCE_REMOVE;
}
@@ -109,9 +109,9 @@ _gdk_broadway_roundtrip_notify (GdkSurface *surface,
/* If there is no remote web client, rate limit update to once a second */
if (local_reply)
g_timeout_add_seconds (1, (GSourceFunc)thaw_clock_cb, g_object_ref (clock));
g_timeout_add_seconds (1, (GSourceFunc)thaw_updates_cb, g_object_ref (surface));
else
_gdk_frame_clock_thaw (clock);
gdk_surface_thaw_updates (surface);
if (timings)
{
@@ -140,7 +140,7 @@ on_frame_clock_after_paint (GdkFrameClock *clock,
GdkBroadwayDisplay *broadway_display;
impl->pending_frame_counter = gdk_frame_clock_get_frame_counter (clock);
_gdk_frame_clock_freeze (gdk_surface_get_frame_clock (surface));
gdk_surface_freeze_updates (surface);
broadway_display = GDK_BROADWAY_DISPLAY (display);
@@ -368,12 +368,12 @@ gdk_broadway_surface_withdraw (GdkSurface *surface)
}
static void
gdk_broadway_surface_move_resize (GdkSurface *surface,
gboolean with_move,
gint x,
gint y,
gint width,
gint height)
gdk_broadway_surface_move_resize_internal (GdkSurface *surface,
gboolean with_move,
gint x,
gint y,
gint width,
gint height)
{
GdkBroadwaySurface *impl = GDK_BROADWAY_SURFACE (surface);
GdkBroadwayDisplay *broadway_display;
@@ -424,6 +424,84 @@ gdk_broadway_surface_move_resize (GdkSurface *surface,
}
}
void
gdk_broadway_surface_move_resize (GdkSurface *surface,
gint x,
gint y,
gint width,
gint height)
{
gdk_broadway_surface_move_resize_internal (surface, TRUE,
x, y,
width, height);
}
static void
gdk_broadway_surface_toplevel_resize (GdkSurface *surface,
gint width,
gint height)
{
gdk_broadway_surface_move_resize_internal (surface, FALSE,
0, 0,
width, height);
}
static void
gdk_broadway_surface_move (GdkSurface *surface,
gint x,
gint y)
{
gdk_broadway_surface_move_resize_internal (surface, TRUE, x, y, -1, -1);
}
static void
gdk_broadway_surface_moved_to_rect (GdkSurface *surface,
GdkRectangle final_rect)
{
GdkSurface *toplevel;
int x, y;
if (surface->surface_type == GDK_SURFACE_POPUP)
toplevel = surface->parent;
else
toplevel = surface->transient_for;
gdk_surface_get_origin (toplevel, &x, &y);
x += final_rect.x;
y += final_rect.y;
if (final_rect.width != surface->width ||
final_rect.height != surface->height)
{
gdk_broadway_surface_move_resize (surface,
x, y,
final_rect.width, final_rect.height);
}
else
{
gdk_broadway_surface_move (surface, x, y);
}
}
static void
gdk_broadway_surface_move_to_rect (GdkSurface *surface,
const GdkRectangle *rect,
GdkGravity rect_anchor,
GdkGravity surface_anchor,
GdkAnchorHints anchor_hints,
gint rect_anchor_dx,
gint rect_anchor_dy)
{
gdk_surface_move_to_rect_helper (surface,
rect,
rect_anchor,
surface_anchor,
anchor_hints,
rect_anchor_dx,
rect_anchor_dy,
gdk_broadway_surface_moved_to_rect);
}
static void
gdk_broadway_surface_raise (GdkSurface *surface)
{
@@ -695,9 +773,9 @@ gdk_broadway_surface_maximize (GdkSurface *surface)
monitor = gdk_display_get_primary_monitor (display);
gdk_monitor_get_geometry (monitor, &geom);
gdk_surface_move_resize (surface,
geom.x, geom.y,
geom.width, geom.height);
gdk_broadway_surface_move_resize (surface,
geom.x, geom.y,
geom.width, geom.height);
}
static void
@@ -718,11 +796,11 @@ gdk_broadway_surface_unmaximize (GdkSurface *surface)
gdk_synthesize_surface_state (surface, GDK_SURFACE_STATE_MAXIMIZED, 0);
gdk_surface_move_resize (surface,
impl->pre_maximize_x,
impl->pre_maximize_y,
impl->pre_maximize_width,
impl->pre_maximize_height);
gdk_broadway_surface_move_resize (surface,
impl->pre_maximize_x,
impl->pre_maximize_y,
impl->pre_maximize_width,
impl->pre_maximize_height);
}
static void
@@ -813,7 +891,9 @@ gdk_broadway_surface_update_popups (GdkSurface *parent)
int new_y = parent->y + popup_impl->offset_y;
if (new_x != popup->x || new_y != popup->y)
gdk_broadway_surface_move_resize (popup, TRUE, new_x, new_y, popup->width, popup->height);
gdk_broadway_surface_move_resize (popup,
new_x, new_y,
popup->width, popup->height);
gdk_broadway_surface_restack_toplevel (popup, parent, TRUE);
}
}
@@ -935,7 +1015,8 @@ update_pos (MoveResizeData *mv_resize,
w, h, &w, &h);
}
gdk_surface_move_resize (mv_resize->moveresize_surface, x, y, w, h);
gdk_broadway_surface_move_resize (mv_resize->moveresize_surface,
x, y, w, h);
}
else
{
@@ -944,7 +1025,7 @@ update_pos (MoveResizeData *mv_resize,
x = mv_resize->moveresize_orig_x + dx;
y = mv_resize->moveresize_orig_y + dy;
gdk_surface_move (mv_resize->moveresize_surface, x, y);
gdk_broadway_surface_move (mv_resize->moveresize_surface, x, y);
}
}
@@ -1311,7 +1392,8 @@ gdk_broadway_surface_class_init (GdkBroadwaySurfaceClass *klass)
impl_class->raise = gdk_broadway_surface_raise;
impl_class->lower = gdk_broadway_surface_lower;
impl_class->restack_toplevel = gdk_broadway_surface_restack_toplevel;
impl_class->move_resize = gdk_broadway_surface_move_resize;
impl_class->toplevel_resize = gdk_broadway_surface_toplevel_resize;
impl_class->move_to_rect = gdk_broadway_surface_move_to_rect;
impl_class->get_geometry = gdk_broadway_surface_get_geometry;
impl_class->get_root_coords = gdk_broadway_surface_get_root_coords;
impl_class->get_device_state = gdk_broadway_surface_get_device_state;

View File

@@ -234,7 +234,7 @@ gdk_content_formats_unref (GdkContentFormats *formats)
* This is meant for debugging and logging.
*
* The form of the representation may change at any time and is
* not guranteed to stay identical.
* not guaranteed to stay identical.
**/
void
gdk_content_formats_print (GdkContentFormats *formats,

View File

@@ -1312,7 +1312,7 @@ gdk_event_get_scroll_deltas (const GdkEvent *event,
* stop scroll event is the signal that a widget may trigger kinetic
* scrolling based on the current velocity.
*
* Stop scroll events always have a a delta of 0/0.
* Stop scroll events always have a delta of 0/0.
*
* Returns: %TRUE if the event is a scroll stop event
*/

View File

@@ -97,10 +97,14 @@ struct _GdkFrameClockPrivate
gint n_timings;
gint current;
GdkFrameTimings *timings[FRAME_HISTORY_MAX_LENGTH];
gint n_freeze_inhibitors;
};
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GdkFrameClock, gdk_frame_clock, G_TYPE_OBJECT)
static void
_gdk_frame_clock_freeze (GdkFrameClock *clock);
static void
gdk_frame_clock_finalize (GObject *object)
{
@@ -114,12 +118,21 @@ gdk_frame_clock_finalize (GObject *object)
G_OBJECT_CLASS (gdk_frame_clock_parent_class)->finalize (object);
}
static void
gdk_frame_clock_constructed (GObject *object)
{
G_OBJECT_CLASS (gdk_frame_clock_parent_class)->constructed (object);
_gdk_frame_clock_freeze (GDK_FRAME_CLOCK (object));
}
static void
gdk_frame_clock_class_init (GdkFrameClockClass *klass)
{
GObjectClass *gobject_class = (GObjectClass*) klass;
gobject_class->finalize = gdk_frame_clock_finalize;
gobject_class->constructed = gdk_frame_clock_constructed;
/**
* GdkFrameClock::flush-events:
@@ -335,7 +348,7 @@ gdk_frame_clock_end_updating (GdkFrameClock *frame_clock)
GDK_FRAME_CLOCK_GET_CLASS (frame_clock)->end_updating (frame_clock);
}
void
static void
_gdk_frame_clock_freeze (GdkFrameClock *clock)
{
g_return_if_fail (GDK_IS_FRAME_CLOCK (clock));
@@ -344,7 +357,7 @@ _gdk_frame_clock_freeze (GdkFrameClock *clock)
}
void
static void
_gdk_frame_clock_thaw (GdkFrameClock *clock)
{
g_return_if_fail (GDK_IS_FRAME_CLOCK (clock));
@@ -352,6 +365,35 @@ _gdk_frame_clock_thaw (GdkFrameClock *clock)
GDK_FRAME_CLOCK_GET_CLASS (clock)->thaw (clock);
}
void
_gdk_frame_clock_inhibit_freeze (GdkFrameClock *clock)
{
GdkFrameClockPrivate *priv;
g_return_if_fail (GDK_IS_FRAME_CLOCK (clock));
priv = clock->priv;
priv->n_freeze_inhibitors++;
if (priv->n_freeze_inhibitors == 1)
_gdk_frame_clock_thaw (clock);
}
void
_gdk_frame_clock_uninhibit_freeze (GdkFrameClock *clock)
{
GdkFrameClockPrivate *priv;
g_return_if_fail (GDK_IS_FRAME_CLOCK (clock));
priv = clock->priv;
priv->n_freeze_inhibitors--;
if (priv->n_freeze_inhibitors == 0)
_gdk_frame_clock_freeze (clock);
}
/**
* gdk_frame_clock_get_frame_counter:
* @frame_clock: a #GdkFrameClock

View File

@@ -105,8 +105,8 @@ struct _GdkFrameTimings
guint slept_before : 1;
};
void _gdk_frame_clock_freeze (GdkFrameClock *clock);
void _gdk_frame_clock_thaw (GdkFrameClock *clock);
void _gdk_frame_clock_inhibit_freeze (GdkFrameClock *clock);
void _gdk_frame_clock_uninhibit_freeze (GdkFrameClock *clock);
void _gdk_frame_clock_begin_frame (GdkFrameClock *clock);
void _gdk_frame_clock_debug_print_timings (GdkFrameClock *clock,

View File

@@ -770,7 +770,7 @@ gdk_gl_context_set_is_legacy (GdkGLContext *context,
* @use_es: whether the context should use OpenGL ES instead of OpenGL,
* or -1 to allow auto-detection
*
* Requests that GDK create a OpenGL ES context instead of an OpenGL one,
* Requests that GDK create an OpenGL ES context instead of an OpenGL one,
* if the platform and windowing system allows it.
*
* The @context must not have been realized.

View File

@@ -264,16 +264,6 @@ void gdk_surface_get_geometry (GdkSurface *surface,
gint *width,
gint *height);
void gdk_surface_move (GdkSurface *surface,
gint x,
gint y);
void gdk_surface_move_resize (GdkSurface *surface,
gint x,
gint y,
gint width,
gint height);
GdkGLContext *gdk_surface_get_shared_data_gl_context (GdkSurface *surface);
G_END_DECLS

View File

@@ -49,6 +49,7 @@ enum {
PROP_DISPLAY,
PROP_MANUFACTURER,
PROP_MODEL,
PROP_CONNECTOR,
PROP_SCALE_FACTOR,
PROP_GEOMETRY,
PROP_WORKAREA,
@@ -100,6 +101,10 @@ gdk_monitor_get_property (GObject *object,
g_value_set_string (value, monitor->model);
break;
case PROP_CONNECTOR:
g_value_set_string (value, monitor->connector);
break;
case PROP_SCALE_FACTOR:
g_value_set_int (value, monitor->scale_factor);
break;
@@ -165,6 +170,7 @@ gdk_monitor_finalize (GObject *object)
{
GdkMonitor *monitor = GDK_MONITOR (object);
g_free (monitor->connector);
g_free (monitor->manufacturer);
g_free (monitor->model);
@@ -198,6 +204,12 @@ gdk_monitor_class_init (GdkMonitorClass *class)
"The model name",
NULL,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
props[PROP_CONNECTOR] =
g_param_spec_string ("connector",
"Connector",
"The connector name",
NULL,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
props[PROP_SCALE_FACTOR] =
g_param_spec_int ("scale-factor",
"Scale factor",
@@ -369,11 +381,32 @@ gdk_monitor_get_height_mm (GdkMonitor *monitor)
return monitor->height_mm;
}
/**
* gdk_monitor_get_connector:
* @monitor: a #GdkMonitor
*
* Gets the name of the monitor's connector, if available.
*
* Returns: (transfer none) (nullable): the name of the connector
*/
const char *
gdk_monitor_get_connector (GdkMonitor *monitor)
{
g_return_val_if_fail (GDK_IS_MONITOR (monitor), NULL);
return monitor->connector;
}
/**
* gdk_monitor_get_manufacturer:
* @monitor: a #GdkMonitor
*
* Gets the name of the monitor's manufacturer, if available.
* Gets the name or PNP ID of the monitor's manufacturer, if available.
*
* Note that this value might also vary depending on actual
* display backend.
*
* PNP ID registry is located at https://uefi.org/pnp_id_list
*
* Returns: (transfer none) (nullable): the name of the manufacturer, or %NULL
*/
@@ -504,6 +537,16 @@ gdk_monitor_set_model (GdkMonitor *monitor,
g_object_notify (G_OBJECT (monitor), "model");
}
void
gdk_monitor_set_connector (GdkMonitor *monitor,
const char *connector)
{
g_free (monitor->connector);
monitor->connector = g_strdup (connector);
g_object_notify (G_OBJECT (monitor), "connector");
}
void
gdk_monitor_set_position (GdkMonitor *monitor,
int x,

View File

@@ -80,6 +80,8 @@ const char * gdk_monitor_get_manufacturer (GdkMonitor *monitor);
GDK_AVAILABLE_IN_ALL
const char * gdk_monitor_get_model (GdkMonitor *monitor);
GDK_AVAILABLE_IN_ALL
const char * gdk_monitor_get_connector (GdkMonitor *monitor);
GDK_AVAILABLE_IN_ALL
int gdk_monitor_get_scale_factor (GdkMonitor *monitor);
GDK_AVAILABLE_IN_ALL
int gdk_monitor_get_refresh_rate (GdkMonitor *monitor);

View File

@@ -36,6 +36,7 @@ struct _GdkMonitor {
GdkDisplay *display;
char *manufacturer;
char *model;
char *connector;
GdkRectangle geometry;
int width_mm;
int height_mm;
@@ -58,6 +59,8 @@ void gdk_monitor_set_manufacturer (GdkMonitor *monitor,
const char *manufacturer);
void gdk_monitor_set_model (GdkMonitor *monitor,
const char *model);
void gdk_monitor_set_connector (GdkMonitor *monitor,
const char *connector);
void gdk_monitor_set_position (GdkMonitor *monitor,
int x,
int y);

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