Compare commits

..

953 Commits

Author SHA1 Message Date
Matthias Clasen
d080a2c482 gtk-demo: Plug memory leaks in the settings demo 2019-12-25 01:10:48 -05:00
Matthias Clasen
682dbe1c9c inspector: Use search instead of filtering for properties
This is mainly to test the search support.
2019-12-24 20:09:48 -05:00
Matthias Clasen
3f5d6bd8b5 listbase: search support
Add a filter to GtkListBase, and move the selection
to the first matching item whenever the filter changes.
This is meant to be used with single selection and
a string filter that is hooked up to a search entry.
2019-12-24 20:09:01 -05:00
Matthias Clasen
98aedb7592 inspector: Add columns to the object tree
Add columnview columns in the object tree.
We do the same for treeview columns.
2019-12-24 15:36:08 -05:00
Matthias Clasen
b1fdd77ede builderlistitemfactory: Precompile the xml
This is the one place where we can really take advantage
of precompiling, since we instantiate this template
over and over.
2019-12-24 15:36:08 -05:00
Matthias Clasen
ed7f507206 builder: Avoid a crash in error cases
Don't leave a dangling pointer behind. I've hit
cases where we crash trying to free it again.
2019-12-24 15:36:08 -05:00
Matthias Clasen
a101e8079f builder: Avoid another critical
Only free an expression if we managed
to create one.
2019-12-24 15:36:08 -05:00
Matthias Clasen
b8faadec64 builder: Avoid a critical
Check that the property exists before trying
to create a property expression, and report
an error if it doesn't.
2019-12-24 15:36:08 -05:00
Matthias Clasen
51b4768fd7 expression: Add a new property expression constructor
Allow creating property expresions from a GParamSpec.
This lets us avoid a critical, and instead report an
error in GtkBuilder if the property does not exist.
2019-12-24 15:36:08 -05:00
Matthias Clasen
8febf5e98a Spread single-click-activate api
This makes sense to have in all the views,
not just GtkListView.
2019-12-24 15:36:08 -05:00
Matthias Clasen
1d9e09aaca printdialog: Port to column view
This is not 100% complete. The search is not there yet.
2019-12-24 15:36:08 -05:00
Matthias Clasen
eecb8092dc printer: Fix the default value of icon-name
Just set this to "printer", so we don't have
to fix it up in the print dialog.
2019-12-24 15:36:08 -05:00
Matthias Clasen
ddd504ddfe printbackend: Add a list model getter
Now that we have a list model for printers,
we can start using it.
2019-12-24 15:36:08 -05:00
Matthias Clasen
4044a8cc6c printbackend: Use a list store 2019-12-24 15:36:08 -05:00
Matthias Clasen
05c869d19b inspector: Expand the actions list 2019-12-24 15:36:08 -05:00
Matthias Clasen
57d635e1a1 inspector: Expand the resource list
This is an experiment with adding a filler column.
2019-12-24 15:36:08 -05:00
Matthias Clasen
2c1a0d3d2e inspector: Expand the property list
It looks better this way.
2019-12-24 15:36:08 -05:00
Matthias Clasen
d5d3b4b991 inspector: Expand the object tree
This is how it used to look, and it looks better that way.
2019-12-24 15:36:08 -05:00
Matthias Clasen
19166f15e3 columnview: Take expand into account
When allocating columns, distribute extra space
to columns that have expand set to TRUE.
2019-12-24 15:36:08 -05:00
Matthias Clasen
fe31c2221c columnviewcolumn: Add an expand property
This will be used to determine how to distribute
available extra space in a column view.
2019-12-24 15:36:08 -05:00
Matthias Clasen
50e8ccf030 gtk-demo: Add more scrolling benchmarks
Add a listview and gridview to the scrolling
benchmarks.
2019-12-24 15:36:08 -05:00
Matthias Clasen
7539fe1acc gtk-demo: Make gridview demo use rubberbanding 2019-12-24 15:36:08 -05:00
Matthias Clasen
ee03ae8b9b Add rubberband api
Add an enable-rubberband property to GtkListView,
GtkGridView and GtkColumnView.
2019-12-24 15:36:08 -05:00
Matthias Clasen
7bf21cf9d2 listbase: Add rubberband selection
Implement the typical rubberband selection, including
autoscroll. This is only useful with multiselection,
and not very compatible with single-click-activate.
Therefore, it is not enabled by default, and needs
to be turned on with the enable-rubber-band property.
2019-12-24 15:36:08 -05:00
Matthias Clasen
466aec41f5 multiselection: Add a copy constructor
Add a function to create a multiselection that
is a copy of an existing selection model. We
can do this efficiently if the original is a
multiselection as well, by just copying the
entire set in on go.
2019-12-24 15:36:08 -05:00
Matthias Clasen
5e9adeb9bf Add GtkMultiSelection
This is implemented using a private GtkSet helper.
2019-12-24 15:36:08 -05:00
Matthias Clasen
c7b2307a0b columnviewtitle: Display a context menu
When the ::header-menu property is set on the
column, use the menu model to create and show
a context menu.
2019-12-24 15:36:08 -05:00
Matthias Clasen
6e838098cb columnviewcolumn: Add a menu property
Add a ::header-menu property that will be used
to create a context menu for the header of the
column.
2019-12-24 15:36:08 -05:00
Matthias Clasen
ee76623e54 Add a selection model test
The test shows that we are failing to emit
::selection-changed in some circumstances.
2019-12-24 15:36:08 -05:00
Matthias Clasen
36aaece297 testcolumnview: Reordering in the column editor
Use Ctrl-Up/Down to move the column around.
2019-12-24 15:36:08 -05:00
Matthias Clasen
4c8de636ce testcolumnview: Flesh out column editor
Turn the column list into an editor with
controls for visibility, resizability, reorderability
and width.
2019-12-24 15:36:08 -05:00
Matthias Clasen
8c086dbdc7 columview: Add autoscroll
Autoscroll when the pointer gets close to the
edge during column resizing or reordering. This
is similar to what the treeview does, but it is
implemented using a tick callback, and has
variable speed.
2019-12-24 15:36:08 -05:00
Matthias Clasen
f86aeaf8cd columnview: Allow to cancel reorder with Escape
The treeview does this too.
2019-12-24 15:36:08 -05:00
Matthias Clasen
c814864a3f columnview: Interactive column reordering
Allow rearranging columns by dragging, in the same
way the treeview does.

We add the "dnd" style class to the header while
it is dragged, and we move the header of the dragged
column to the end of its parents children, so that
it gets drawn on top.
2019-12-24 15:36:08 -05:00
Matthias Clasen
9e9d4d914e columnviewcolumn: Add a reorderable property
This will be used for interactive column reordering
in the future.
2019-12-24 15:36:08 -05:00
Matthias Clasen
8f2351d5d3 columnviewlayout: Use header allocation for titles
Normally, this will be identical to the column
allocation, but we will temporarily change it
during column reordering.
2019-12-24 15:36:08 -05:00
Matthias Clasen
4817c7757b columnviewcolumn: Add reordering helpers
Add helper functions that let us temporarily give
a different allocation to headers. These will be
used to implement interactive column reordering
in GtkColumnView.
2019-12-24 15:36:08 -05:00
Matthias Clasen
a44c4b4877 columnviewtitle: Invert on release
This is necessary to make drag-to-reorder work
without triggering inversion.
2019-12-24 15:36:08 -05:00
Matthias Clasen
f8a14427ea columnview: Interactive column resizing
This copies just enough of the treeview code to
get columns moving.
2019-12-24 15:36:08 -05:00
Matthias Clasen
9d0904a445 columnviewcolumn: Add a helper
We need to check whether clicks are in the headers
of columns, so let the column view get at the the
header widget.
2019-12-24 15:36:08 -05:00
Matthias Clasen
4a659c169d columnviewcolumn: Add a resizable property
This will be used for interactive column resizing
in the future.
2019-12-24 15:36:08 -05:00
Matthias Clasen
5ca53555c7 Turn GtkRecentInfo into an object
This is in preparation to eventually using
a list model of recent infos.
2019-12-24 15:36:08 -05:00
Matthias Clasen
0bbc074e08 gtk-demo: Add row reordering to the settings demo 2019-12-24 15:36:08 -05:00
Matthias Clasen
7af244944a gtk-demo: Add filtering to the settings demo
A demo of filtering with lists was missing so far.
2019-12-24 15:36:08 -05:00
Matthias Clasen
ae084d2929 gtk-demo: Crank up max columns of gridview
This lets us fit more cells on screen.
2019-12-24 15:36:08 -05:00
Matthias Clasen
fe3dd5cd8b gtk-demo: Make gridview content switchable
Add a dropdown to switch out the item factory.
2019-12-24 15:36:08 -05:00
Matthias Clasen
3dbac6b133 gtk-demo: Add sorting to the gridview demo 2019-12-24 15:36:08 -05:00
Matthias Clasen
2cb5ce8c72 gtk-demo: Cosmetic changes for the flowbox demo
Mention the size of the dataset.
2019-12-24 15:36:08 -05:00
Matthias Clasen
8ae6e58e0c gtk-demo: Cosmetic changes to the file browser demo
Mention that it involves switching between
different views.
2019-12-24 15:36:08 -05:00
Matthias Clasen
6eebc9183a gtk-demo: Cosmetic changes for the weather demo
Give the weather demo a size and a title, and mention
the size of the dataset in the description.
2019-12-24 15:36:08 -05:00
Matthias Clasen
b84780cc98 gtk-demo: Cosmetic changes to the clocks demo
Give the clocks demo a title and size,
and tweak the description.
2019-12-24 15:36:08 -05:00
Matthias Clasen
46a6ab68f2 gtk-demo: Demo columnview sorting
Enhance the settings demo to have a sortable column.
2019-12-24 15:36:08 -05:00
Matthias Clasen
e5c57d10d7 filechooser: Use a dropdown for choices 2019-12-24 15:36:08 -05:00
Matthias Clasen
9aed6a2b56 filechooser: Use a dropdown for the filter combo 2019-12-24 15:36:08 -05:00
Matthias Clasen
843fa70bef inspector: Use dropdowns in the visual page
Convert everything in the visual page to dropdowns.
2019-12-24 15:36:08 -05:00
Matthias Clasen
2ea918a5e7 inspector: Use a dropdown for size groups
Use a GtkDropDown for the modes of size groups.
2019-12-24 15:36:08 -05:00
Matthias Clasen
f7608a2119 inspector: Use a dropdown for controllers
Use a GtkDropDown for the phases of event controllers.
2019-12-24 15:36:07 -05:00
Matthias Clasen
f55528fd10 inspector: Use a dropdown for attribute mapping
Use a GtkDropDown for the attribute mapping editor.
2019-12-24 15:36:07 -05:00
Matthias Clasen
1d7322ed63 inspector: Use dropdowns in property editor
Replace combo boxes by dropdowns in the property editor.
2019-12-24 15:36:07 -05:00
Matthias Clasen
f3dc528e7d Add GtkDropDown
This is a simple drop down control using list models.
2019-12-24 15:36:07 -05:00
Matthias Clasen
6265a60663 columnview: Add a helper
The column code needs to get access to the
listitem widgets that are children of the listview,
so add a getter.
2019-12-24 15:36:07 -05:00
Matthias Clasen
08bbf44602 columnview: Add column reordering
Add an API to allow reordering columns.
2019-12-24 15:36:07 -05:00
Matthias Clasen
640f165a81 columnviewcolumn: Add a fixed-width property
When fixed-width is set to a value > -1, we make the
measure function of cell and title widgets return this
width, and we set overflow to hidden.
2019-12-24 15:36:07 -05:00
Matthias Clasen
34cbaa9057 columnview: Implement horizontal scrolling
The listview inside always thinks it gets its full size,
and updates its horizontal adjustment accordingly.

So keep our own adjustment, and update it in size_allocate.
2019-12-24 15:36:07 -05:00
Matthias Clasen
2f666332ea columnview: Revise scroll-minimum handling
Tweak the behavior slightly. We don't show
a scrollbar as long as we have at least
min-size available, but we still give the
entire size to the child, up to nat-size.

This matches how viewports handle scroll-minimum.
2019-12-24 15:36:07 -05:00
Matthias Clasen
972090f34d column: Add a visible property
This lets us hide columns, which is useful.
2019-12-24 15:36:07 -05:00
Matthias Clasen
6ab8b1cfe5 inspector: Touch up list styling
This is just the minimal amount of work to make
headers recognizable.
2019-12-24 15:36:07 -05:00
Matthias Clasen
84fd2290a6 inspector: Use a column view for actions
A straight conversion from list box to column view.
2019-12-24 15:36:07 -05:00
Matthias Clasen
55f9e86d67 inspector: Make the resource list sortable
This is using a GtkTreeListRowSorter to keep expanded
state of the tree while changing the sorting.
2019-12-24 15:36:07 -05:00
Matthias Clasen
9892831d52 inspector: Use a column view for the resource list
A conversion from tree view to column view.
2019-12-24 15:36:07 -05:00
Matthias Clasen
baff649ca6 inspector: Use a column view for properties
Just a straight conversion from list box to column view.
2019-12-24 15:36:07 -05:00
Matthias Clasen
921ff0460b columnview: Add a sort-by api 2019-12-24 15:36:07 -05:00
Matthias Clasen
cab09d27db columnview: Document sorting
Add a paragraph outlining how sorting is set up
for GtkColumnView.
2019-12-24 15:36:07 -05:00
Matthias Clasen
65b3a9358a docs: Fix misc typos and omissions 2019-12-24 15:36:07 -05:00
Matthias Clasen
649bcc69e3 docs: Add more private headers to ignore 2019-12-24 15:36:07 -05:00
Matthias Clasen
2357771bd9 treelistmodel: Small documentation tweaks 2019-12-24 15:36:07 -05:00
Matthias Clasen
d53a0ba584 sorter: Small documentation fixes 2019-12-24 15:36:07 -05:00
Matthias Clasen
e2f78e95b2 numericsorter: Small documentation improvements 2019-12-24 15:36:07 -05:00
Matthias Clasen
dea3c8aed0 multisorter: Small documntation improvements 2019-12-24 15:36:07 -05:00
Matthias Clasen
f2a82e7d35 multifilter: Small documentation improvements 2019-12-24 15:36:07 -05:00
Matthias Clasen
9ff85899d0 builderlistitemfactory: Add an example to the docs 2019-12-24 15:36:07 -05:00
Matthias Clasen
602d141a7b maplistmodel: Add an example to the docs 2019-12-24 15:36:07 -05:00
Matthias Clasen
0bed5a8b9d stringfilter: Documnentation additions 2019-12-24 15:36:07 -05:00
Matthias Clasen
f2a50fa590 filter: Documentation fixes 2019-12-24 15:36:07 -05:00
Matthias Clasen
f833959acd filterlistmodel: Documentation fixes 2019-12-24 15:36:07 -05:00
Matthias Clasen
02168260e0 expression: Small documentation fixes 2019-12-24 15:36:07 -05:00
Matthias Clasen
68fbb59f82 docs: Add gtk_expression_watch_unwatch 2019-12-24 15:36:07 -05:00
Matthias Clasen
e7f3a4f61a expression: Correct an example in the docs 2019-12-24 15:36:07 -05:00
Matthias Clasen
e32ae895e3 Add some tests for new GtkBuilder syntax
Some valid and invalid examples for <closure>,
<lookup> and <constant>.
2019-12-24 15:36:07 -05:00
Matthias Clasen
44c5d47ed8 gtk-builder-tool: Minimally validate <binding>
Check that the toplevel property name is legit.
2019-12-24 15:36:07 -05:00
Matthias Clasen
a9f963b5d9 multifilter: Fix a few annotations 2019-12-24 15:36:07 -05:00
Matthias Clasen
0a711ec0b2 builderlistitemfactory: Fix a few annotations 2019-12-24 15:36:07 -05:00
Matthias Clasen
1630482d13 treelistrowsorter: Fix a doc typo 2019-12-24 15:36:07 -05:00
Matthias Clasen
bdaa41184f columnviewcolumn: Fix a type mismatch
The column-view property was declared with the wrong
type. This was causing criticals in the inspector.
2019-12-24 15:36:07 -05:00
Matthias Clasen
0a36ba0611 listitemwidget: Fix single-click-activate
This was broken by the renaming of ::contains-pointer-focus
to ::contains-pointer. Fix it up.
2019-12-24 15:36:07 -05:00
Matthias Clasen
cc39cc2e8d Fix gtk_column_view_create_cells
This code was assuming that the listitem widgets
are children of the column view, which they aren't.
2019-12-24 15:36:07 -05:00
Matthias Clasen
51e2a51dfd filterlistmodel: Remove pre-filter remnants
We are not using the filter func typdef anymore.
2019-12-24 15:36:07 -05:00
Matthias Clasen
90b32cac0b Add filter test to testsuite 2019-12-22 23:12:21 -05:00
Matthias Clasen
b56cfc5293 Add a test for multi filter unreffing
This tests the fix in the previous commit.
2019-12-22 23:12:21 -05:00
Matthias Clasen
7bb1f036d6 multifilter: Remove an extraneous unref
The sequence is using unref as free func,
no need to ido it ourselves.
2019-12-22 23:12:21 -05:00
Benjamin Otte
0cd203b07d testsuite: Add tests for GtkTreeListSorter 2019-12-18 05:48:03 +01:00
Matthias Clasen
86b29d4d7a Add GtkTreeListRowSorter
This is a special-purpose sorter that can
apply the sorting of another sorter to the
levels of a GtkTreeListModel.
2019-12-18 05:48:02 +01:00
Benjamin Otte
3ffb005135 testcolumnview: Add sorters 2019-12-18 05:48:02 +01:00
Matthias Clasen
a4b15d205e column view title: Show sort indicators 2019-12-18 05:48:02 +01:00
Matthias Clasen
0b4f75cf25 columnview: Add sorting
This is a somewhat large commit that:

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

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

- Adds a writable GtkColumnViewColumn::sorter property
This allows defining per-column sorters. Whenever an application sets a
sorter for a column, the header becomes clickable and whenever
a header is clicked, that column's sorter is prepended to the list of
sorters, unless it is already the first sorter, in which case we invert
its order. No column can be in the list more than once.
2019-12-18 05:48:02 +01:00
Matthias Clasen
163477acfb gtk-demo: Add a large grid demo
This is similar to the flowbox demo, but much bigger.
2019-12-18 05:45:39 +01:00
Matthias Clasen
f80335505e listview: Add single-click-activate
Add a single-click-activate property to GtkListView.
2019-12-18 05:45:39 +01:00
Matthias Clasen
ffdcde53f5 listitemwidget: Add single-click-activate
Add a mode to GtkListItemWidget that activates on
single click and selects on hover. Make
GtkListItemManager set this on its items
when its own 'property' of the same name is set.
2019-12-18 05:45:39 +01:00
Matthias Clasen
5d836b5e15 builder-tool: Pass through CDATA where it makes sense
This avoids a ton of escaping for
GtkBuilderListItemFactory::bytes.
2019-12-18 05:45:39 +01:00
Matthias Clasen
539213133f docs: Reorganize list widgets in their own chapter 2019-12-18 05:45:39 +01:00
Benjamin Otte
6977a03f65 fontchooserwidget: Port to listmodels
The port is kind of evil, in that it stores either a PangoFontFamily or a
PangoFontFace in the list, depending on if the fontchooser is configured
to select fonts or faces.
It also does not cache the font description anymore, so more calls to
pango_font_describe() may happen.

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

These changes depend on Pango 1.46's introduction of listmodels and
various new getters, so the dependency has been upgraded.
2019-12-18 05:45:39 +01:00
Matthias Clasen
0875374b1d Add some tests for expression binding
In particular, test that expressios can deal with object == this.
2019-12-18 05:45:39 +01:00
Benjamin Otte
fe1ce2aaf8 expression: Allow passing a this object to bind()
This gives a bit more control over the arguments passed to expressions.
2019-12-18 05:45:39 +01:00
Benjamin Otte
a81429c10f widget: Do parent_class handling properly
The previous cosde did not actually query the parent class, it just did
a very complicated C cast.
2019-12-18 05:45:39 +01:00
Benjamin Otte
2f52d98ef4 gtk-demo: Add a Clocks demo
This demo is meant to showcase expressions.

It also needs the fixes in glib 2.64 to work properly.
2019-12-18 05:45:39 +01:00
Benjamin Otte
5a076b0c2f xxx: Add a hack to make paintables transform to/from objects
See also: https://gitlab.gnome.org/GNOME/glib/merge_requests/1251
2019-12-18 05:45:39 +01:00
Benjamin Otte
69f59109ee inspector: Remove private struct for prop editor 2019-12-18 05:45:39 +01:00
Benjamin Otte
6bf508ce73 inspector: Make Controller page a GtkWidget 2019-12-18 05:45:39 +01:00
Benjamin Otte
ae26ce017b inspector: Remove private struct from controllers 2019-12-18 05:45:39 +01:00
Benjamin Otte
0a126f65fb columnview: Add header
This uses a custom GtkColumnViewTitle widget. So far that widget is
pretty boring, but that will change once we added
resizing, reordering, dnd, sorting, hiding/showing of columns or
whatever UIs we want.
2019-12-18 05:45:39 +01:00
Benjamin Otte
6d0695260d tests: Add testcolumnview 2019-12-18 05:45:37 +01:00
Benjamin Otte
a43e0b1e62 columnview: Add a custom LayoutManager
The ColumnView now allocates column widths first and then the individual
rows use the new layout manager which looks at the column allocations to
allocate their children.
2019-12-15 23:33:04 +01:00
Benjamin Otte
01d4a28c9f constraint-editor: Don't poke around in widget internals 2019-12-15 23:33:04 +01:00
Benjamin Otte
052343ca7d columnview: Fix styling with Adwaita
- Use "treeview" as the node name
- Add .view style class
2019-12-15 23:33:04 +01:00
Benjamin Otte
7f4260f97e inspector: Port object tree to GtkColumnView 2019-12-15 23:33:04 +01:00
Benjamin Otte
2b42f0fcb3 columnview: Add GtkColumnViewCell
It's a GtkListItemWidget subclass that tracks the column it belongs to
and allows the column to track it.

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

We're doing lots of dancing from one object to another here, but this
will hopefully get simpler with further commits.
2019-12-15 23:33:04 +01:00
Benjamin Otte
7c402bcf2c listitemfactory: Reorganize vfuncs
Instead of bind/rebind/update/unbind, we now just have update, and the
factories get to interpret that in the way they want.
2019-12-15 23:33:04 +01:00
Benjamin Otte
6d73e3a6fa listitem: Make this a GObject
This splits GtkListItem into 2 parts:

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

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

Related: #2214
2019-12-15 23:33:04 +01:00
Benjamin Otte
01cdc67db0 Add GtkSignalListItemFactory
So the poor Rust users can actually use this.

I would totally not use this ever!
2019-12-15 23:33:04 +01:00
Benjamin Otte
77c9d0d0fb columnview: Allow adding/removing columns
... and make that work in UI files via <child>, too.
2019-12-15 23:33:04 +01:00
Benjamin Otte
3cc9fa9f67 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-12-15 23:33:04 +01:00
Benjamin Otte
181b9655ef 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-12-15 23:33:04 +01:00
Benjamin Otte
1eab9ba350 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-12-15 23:33:04 +01:00
Benjamin Otte
d1d0adeae9 listbase: Take over anchor handling
With that, pretty much all code but allocating the widgets is gone from
the gridview and listview.
2019-12-15 23:33:04 +01:00
Benjamin Otte
64a2f04006 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-12-15 23:33:04 +01:00
Benjamin Otte
c835bb30d1 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-12-15 23:33:04 +01:00
Benjamin Otte
96d333f649 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-12-15 23:33:04 +01:00
Benjamin Otte
66142ae74f listbase: Move orientable implementation here 2019-12-15 23:33:04 +01:00
Benjamin Otte
75f539b3a4 listbase: Move selection handling here 2019-12-15 23:33:04 +01:00
Benjamin Otte
ad12914c55 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-12-15 23:33:04 +01:00
Benjamin Otte
f614011569 listbase: Move GtkScrollable implementation
Shared code between GtkGridView and GtkListView.
2019-12-15 23:33:04 +01:00
Benjamin Otte
013db26d22 Add GtkListBase
This is a base item for GTK's list widgets so they can share some (read:
hopefully a lot of) code.
2019-12-15 23:33:04 +01:00
Benjamin Otte
9fab1b3d25 gridview: Simplify allocation code
It doesn't fix the bug I'm after, but it looks a lot better.
2019-12-15 23:33:04 +01:00
Benjamin Otte
c3bb95d7d9 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-12-15 23:33:04 +01:00
Benjamin Otte
27a891adb8 demo: Add a file browser demo 2019-12-15 23:33:04 +01:00
Benjamin Otte
94b162829c gridview: Add move keybindings 2019-12-15 23:33:04 +01:00
Benjamin Otte
e54f3f68a0 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-12-15 23:33:04 +01:00
Benjamin Otte
ddc665bb01 gridview: Add a focus tracker
... and use that to properly update selections when moving around with
the arrow keys.
2019-12-15 23:33:04 +01:00
Benjamin Otte
d0495e36e6 gridview: Implement list.scroll-to action 2019-12-15 23:33:04 +01:00
Benjamin Otte
4444bb3d98 gridview: Add activation 2019-12-15 23:33:04 +01:00
Benjamin Otte
b9616124cb 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-12-15 23:33:04 +01:00
Benjamin Otte
6218a27daf gridview: Implement the list.select-item action 2019-12-15 23:33:04 +01:00
Benjamin Otte
51ecc2d566 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-12-15 23:33:04 +01:00
Benjamin Otte
050bd6d5e3 gridview: Implement anchors and scrolling 2019-12-15 23:33:04 +01:00
Benjamin Otte
0229f11784 widget: Add gtk_widget_get_size()
A little bit of convenience.
2019-12-15 23:33:04 +01:00
Benjamin Otte
cee950b455 listitemmanager: Handle NULL factory
Just don't call it and create empty listitems.
2019-12-15 23:33:04 +01:00
Timm Bäder
3a5f47c3b8 demo: Use a listview as sidebar 2019-12-15 23:33:04 +01:00
Benjamin Otte
484f804ba6 gtk-demo: Introduce awards
We need a way to get a useful listbox, so here we go!
2019-12-15 23:33:04 +01:00
Benjamin Otte
5b96335956 builder: Autofill scope property of listitemfactory
I couldn't come up with a better way to automatically inherit the scope
in the builder list item factory that didn't involve a magic
incantation in the XML file. And I do not want developers to know magic
incantations to do a thing that should pretty much always be done.
2019-12-15 23:33:04 +01:00
Benjamin Otte
61362af27b builderlistitemfactory: Add scope argument
This way, the scope used when creating builder instances can be
influenced. This way, callbacks can be passed into the factory.
2019-12-15 23:33:04 +01:00
Benjamin Otte
fc82f5fe29 listitemfactory: Make the builder factory properly buildable
Turn the construct arguments into construct properties so that they can
be set from ui files.
2019-12-15 23:33:04 +01:00
Benjamin Otte
5ae2c1fdca listview: Add move keybindings
My god, these are a lot.

And my god, these are complicated to get right.
2019-12-15 23:33:04 +01:00
Benjamin Otte
eba9ec613d listview: Add gtk_list_view_get_position_at_y() 2019-12-15 23:33:04 +01:00
Benjamin Otte
61fc0a6a59 listitem: Add "listitem.select" action and keybindings for it
In fact, grab space with all modifiers to toggle selection of the
current item.
2019-12-15 23:33:03 +01:00
Benjamin Otte
250760468b listview: Add a focus tracker
This ensures that the row with the input focus always stays available,
even when scrolled out of view.
2019-12-15 23:33:03 +01:00
Benjamin Otte
9d5063cf68 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-12-15 23:33:03 +01:00
Benjamin Otte
c4af364bfb listview: Track focus movements and update selection
When focus moves via tab/arrow, we need to select the new item.
2019-12-15 23:33:03 +01:00
Benjamin Otte
3e1cad5755 listview: Implement activation
- a GtkListview::activate signal
- a GtkListItem::activatable property
- activate list items on double clicks and <Enter> presses
2019-12-15 23:33:03 +01:00
Benjamin Otte
42c077443e 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-12-15 23:33:03 +01:00
Benjamin Otte
7a49d2e848 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-12-15 23:33:03 +01:00
Benjamin Otte
462953cac0 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-12-15 23:33:03 +01:00
Benjamin Otte
5b5ab5c592 inspector: Use a GtkTreeExpander in the object tree 2019-12-15 23:33:03 +01:00
Benjamin Otte
d89f9b6684 inspector: Use a treeexpander in the recorder 2019-12-15 23:33:03 +01:00
Benjamin Otte
71f104782a 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-12-15 23:33:03 +01:00
Benjamin Otte
297a2795c3 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-12-15 23:33:03 +01:00
Benjamin Otte
081645186d 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-12-15 23:33:03 +01:00
Benjamin Otte
20201662f1 listview: Pass the CSS name of listitems to the manager
... instead of hardcoding "row".
2019-12-15 21:11:03 +01:00
Benjamin Otte
3c97226e66 gridview: Implement GtkOrientable
Again, this is just the skeleton, because the Gridview does nothing yet.
2019-12-15 21:11:03 +01:00
Benjamin Otte
6b4b1e1921 gridview: Add factory handling
Just copy the listview APIs.

Code still doesn't do anything with it.
2019-12-15 21:11:03 +01:00
Benjamin Otte
246421f92c 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-12-15 21:11:03 +01:00
Benjamin Otte
603055b70d textview: Make cursor work when blinking is disabled 2019-12-15 21:10:29 +01:00
Benjamin Otte
6a26bb0e2f gtk-demo: Add a rough start at a Weather demo
This demos a horizontal listview.
2019-12-15 21:10:29 +01:00
Benjamin Otte
81bc2117b2 listview: Implement GtkOrientable 2019-12-15 21:10:28 +01:00
Benjamin Otte
f307f99275 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-12-15 21:10:28 +01:00
Benjamin Otte
8157408df8 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-12-15 21:10:28 +01:00
Benjamin Otte
9630b9f244 listview: Add list.scroll_to_item action
The action scrolls the given item into view.

Listitems activate this action when they gain focus.
2019-12-15 21:10:28 +01:00
Benjamin Otte
4b277dd47a testlistview: Load icons async
Speeds up loading by 4x, because out of view icons aren't loaded
anymore.
2019-12-15 21:10:28 +01:00
Benjamin Otte
5fcdf00a1a testlistview: Port to directory list 2019-12-15 21:10:28 +01:00
Benjamin Otte
48e1a3cc06 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-12-15 21:10:28 +01:00
Benjamin Otte
8c5b077555 listitemfactory: Split implementation out
.. into gtkfunctionslistitemfactory.c

Now we can add a different implmenetation.
2019-12-15 21:10:28 +01:00
Benjamin Otte
023ff509b2 listitemfactory: vfuncify
No functional changes other than a new indirection.
2019-12-15 21:10:28 +01:00
Benjamin Otte
a0a7da2e3b 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-12-15 21:10:28 +01:00
Benjamin Otte
b7ae37ab3d listview: Add gtk_list_view_set_show_separators()
Do the same thing that GtkListBox does in commit
0249bd4f8a
2019-12-15 21:10:28 +01:00
Benjamin Otte
6d8c6bb2f7 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-12-15 21:10:28 +01:00
Benjamin Otte
b00c04a986 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-12-15 21:10:28 +01:00
Benjamin Otte
62da088018 gridview: Implement GtkScrollable
We can now scroll all the nothing we display.

We also clip it properly.
2019-12-15 21:10:28 +01:00
Benjamin Otte
6d93197f08 listitemmanager: Move list of listitems here
All the listview infrastructure moved with it, so the next step is
moving that back...
2019-12-15 21:10:28 +01:00
Benjamin Otte
72ce2ff512 wayland: Remove function declaration for nonexisting function 2019-12-15 21:10:28 +01:00
Benjamin Otte
cfd503893c gridview: Add API for setting number of columns
The API isn't used yet.
2019-12-15 21:10:28 +01:00
Benjamin Otte
a2ec02875a gtk: Add a GtkGridView skeleton 2019-12-15 21:10:28 +01:00
Benjamin Otte
07036e28c0 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-12-15 21:10:28 +01:00
Benjamin Otte
0b3135bf14 listview: Add initial support for displaying selections 2019-12-15 21:10:28 +01:00
Benjamin Otte
2ea5607f79 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-12-15 21:10:28 +01:00
Benjamin Otte
35e516f996 listview: Add selection properties to ListItem
This just brings the infrastructure into place, we're not using the
properties yet.
2019-12-15 21:10:28 +01:00
Benjamin Otte
b856fe66b9 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-12-15 21:10:28 +01:00
Benjamin Otte
7d01e25558 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-12-15 21:10:28 +01:00
Benjamin Otte
b99db2a60b 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-12-15 21:10:28 +01:00
Benjamin Otte
085e4ad273 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-12-15 21:10:28 +01:00
Benjamin Otte
72dea0d5e9 testlistview: Show the row number
Always show the current row. This is mostly useful for debugging, not
for beauty.
2019-12-15 21:10:28 +01:00
Benjamin Otte
6dd18fafaa 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-12-15 21:10:28 +01:00
Benjamin Otte
9b9aec360e 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-12-15 21:10:28 +01:00
Benjamin Otte
0db67c9709 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-12-15 21:10:28 +01:00
Benjamin Otte
c935bf5648 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-12-15 21:10:28 +01:00
Benjamin Otte
94a9752c43 tests: Make animating listview do random resorts 2019-12-15 21:10:28 +01:00
Benjamin Otte
de005bd1d6 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-12-15 21:10:28 +01:00
Benjamin Otte
134db60479 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-12-15 21:10:28 +01:00
Benjamin Otte
662b142c86 listview: Add GtkListItem
GtkListItem is a generic row widget that is supposed to replace
GtkListBoxRow and GtkFlowBoxChild.
2019-12-15 21:10:28 +01:00
Benjamin Otte
22a9001103 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-12-15 21:10:28 +01:00
Benjamin Otte
42b62c7ba2 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-12-15 21:10:28 +01:00
Benjamin Otte
8bf19f7cbf 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-12-15 21:10:28 +01:00
Benjamin Otte
15dce5c26c listview: Implement GtkScrollable
Scrolling in a very basic form is also supported
2019-12-15 21:10:28 +01:00
Benjamin Otte
742dfd919d 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-12-15 21:10:28 +01:00
Benjamin Otte
b5e54c1e7d 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-12-15 21:10:28 +01:00
Benjamin Otte
9756330b75 gtk: Add a GtkListView skeleton 2019-12-15 21:10:28 +01:00
Benjamin Otte
8126b24a78 builder: Add <binding> tag
The tag contains an expression that it then gtk_expression_bind()s to
the object it is contained in.
2019-12-15 21:10:28 +01:00
Benjamin Otte
9520a04d26 builder: Allow text content in <lookup>
<lookup>foo</lookup>
is now short for
  <lookup>
    <constant>foo</constant>
  </lookup>
ie it looks up the object with the given name so it can then do a
property lookup with it.

This is the most common operation, so it's a nice shortcut.
2019-12-15 21:10:28 +01:00
Benjamin Otte
aa1d21a7ae builder: Allow <constant> without a type
A constant without a type is assumed to be an object. This is the most
common case and allows
  <constant>foo</constant>
without requiring updates to the type whenever the foo object changes.
2019-12-15 21:10:28 +01:00
Benjamin Otte
1c354586d0 builder: Make <lookup> type optional
If no type is set, use the type of the expression.
2019-12-15 21:10:28 +01:00
Benjamin Otte
90277fba71 gtk-demo: Make fishbowl info text use bindings
It's a good demo for how bindings can format multiple properties into an
informative string with 1 line of code (and 5 lines of XML).
2019-12-15 21:10:28 +01:00
Matthias Clasen
830939d8c7 sorter: Add tests
Some basic tests for GtkSorter.
2019-12-15 21:10:28 +01:00
Benjamin Otte
900616ec7a sortlistmodel: Make sort stable
The sort of the sortlistmodel is now stable with respect to the original
list model.

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

Or in other words: The model guarantees a total order based on the
item's position in the original model.
2019-12-15 21:10:28 +01:00
Benjamin Otte
2c047aa76f sortlistmodel: Redo the way we store the items
We need to keep this data around for changes in future commits where we
make the sorting stable.

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

This change does not do any behavioral changes.
2019-12-15 21:10:28 +01:00
Matthias Clasen
c1071d8c5d Redo sort list model with GtkSorter
Reshuffle the api to take full advantage
of GtkSorter. Update all callers.
2019-12-15 21:10:28 +01:00
Matthias Clasen
7c9ebaef3d Add GtkNumericSorter
This sorter compares numbers obtained from items
by evaluating an expression.
2019-12-15 21:10:28 +01:00
Matthias Clasen
90c75c8b9a Add GtkMultiSorter
This is a sorter that tries multiple sorters in turn.
2019-12-15 21:10:28 +01:00
Matthias Clasen
3c96f65094 Add GtkStringSorter
This is a GtkSorter implementation collating strings
2019-12-15 21:10:28 +01:00
Matthias Clasen
06fbc82ddf Add GtkCustomSorter
This is a GtkSorter implementation which uses a GCompareDataFunc.
2019-12-15 21:10:28 +01:00
Matthias Clasen
575b42c481 Add GtkSorter
This is a helper object for sorting, similar to GtkFilter.
2019-12-15 21:10:28 +01:00
Benjamin Otte
10631c979d Add GtkOrdering
This is an enum that we're gonna use soon and it's worth introducing as a
separate commit.

The intention is to have meaningful names for return values in
comparison functions.
2019-12-15 21:10:28 +01:00
Matthias Clasen
c4ce8ef60f More expression tests
Test type mismatches, and the this pointer
during evaluation.
2019-12-15 21:10:28 +01:00
Benjamin Otte
04df027567 expression: Invalidate bindings before destroying them
Use a weak ref to invalidate bindings. Make sure that this happens
before creating any watches, so that notifies from the
watched expression about changes will not trigger set_property() calls
during dispose()/finalize().

Invalidating also ensures that the watches aren't removed, which can
trigger warnings if the watches are watching the object itself, and the
weak refs cannot be removed anymore.
2019-12-15 21:10:28 +01:00
Benjamin Otte
fc0751a909 expression: Add gtk_expression_bind()
Add a simple way to bind expressions to object properties. This is
essentially the thing to replace g_object_bind_property().
2019-12-15 21:10:28 +01:00
Benjamin Otte
03815102d5 testsuite: Add expression tests 2019-12-15 21:10:28 +01:00
Benjamin Otte
e8613aab9c expression: Add the ability to watch an expression 2019-12-15 21:10:28 +01:00
Benjamin Otte
b603f472ab builder: Add support for parsing expressions 2019-12-15 21:10:28 +01:00
Benjamin Otte
b4b6be9f6e filter: Add tests
Some basic tests for GtkFilter
2019-12-15 21:10:28 +01:00
Benjamin Otte
bb12d3d8ca Add GtkMultiFilter, GtkAnyFilter, GtkEveryFilter
GtkMultiFilter is the abstract base class for managing multiple child
filter.
GtkAnyFilter and GtkEveryFilter are the actual implementations.
2019-12-15 21:10:28 +01:00
Benjamin Otte
52e385672a filter: Add GtkStringFilter
Users provide a search filter and an expression that evaluates the items
to a string and then the filter goes and matches those strings to the
search term.
2019-12-15 21:10:28 +01:00
Benjamin Otte
ca2ebaf90f expression: Make property expression allow subexpressions 2019-12-15 21:10:28 +01:00
Benjamin Otte
46c042ed06 expression: Add GtkObjectExpression
Weak refs break cycles...
2019-12-15 21:10:27 +01:00
Benjamin Otte
e462a2bdcc Add GtkExpression
GtkExpressions allow looking up values from objects.

There are a few simple expressions, but the main one is the closure
expression that just calls a user-provided closure.
2019-12-15 21:10:27 +01:00
Benjamin Otte
bb59b48871 filterlistmodel: Rewrite to use GtkFilter 2019-12-15 21:10:27 +01:00
Benjamin Otte
da413fa72d tests: Remove testtreemodel test
testlistview does everything this test does.
2019-12-15 21:10:27 +01:00
Benjamin Otte
75556a3485 Add GtkCustomFilter 2019-12-15 21:10:27 +01:00
Benjamin Otte
53401e5d89 Add GtkFilter 2019-12-15 21:10:27 +01:00
Benjamin Otte
56838cab86 Add GtkDirectoryList
Adds a new listmodel called GtkDirectoryList that lists the children of
a GFile as GFileInfos.

This is supposed to be used by the filechooser.
2019-12-15 21:10:27 +01:00
Benjamin Otte
0a551b9b2a gdk: Add GDK_DECLARE_EXPORTED_TYPE()
This is like G_DECLARE_FINAL_TYPE(), except it doesn't make the class
struct public, so internally all the subclassing in the world can
happen.

Some subtle differences:
- It marks the get_type() function as G_GNUC_CONST
- It doesn't require the parent type
- It uses G_DEFINE_AUTOPTR_CLEANUP_FUNC() instead of the private glib
  chainup method.

Port a bunch of GDK and the whole event controller + gesture machinery
to provew that it works.

As a side effect, we gained a bunch of missing autocleanups.
2019-12-15 21:10:27 +01:00
Benjamin Otte
ed24f93fb9 popover: Remove unneeded vfunc
The vfunc is identical to the GtkWidget implementation it replaces. So
just keep using that one.
2019-12-15 21:07:54 +01:00
Benjamin Otte
c4043a8eef treelistmodel: Improve docs
- Move into its own section
- Split GtkTreeListRow into its own document

Trees are weird with listmodels and they deserve their own treatment,
they shouldn't be mushed up with the rest of the list machinery.
2019-12-15 21:07:54 +01:00
Benjamin Otte
dff86c0e12 eventcontrollermotion: Add getters for the properties
... and use them.

Also, rename them from is/contains-pointer-focus to is/contains-pointer,
that's clear enough and not too long.

Finally, adapt the semantics of contains-pointer to mirror
GtkEventControllerKey::contains-focus. If is-pointer is set, so is
contains-pointer, they are not exclusive.
Which is what all users of this property wanted, too.
2019-12-15 21:07:54 +01:00
Matthias Clasen
9a5ec33d61 Merge branch 'fix-x11-cursor-crash' into 'master'
x11: Only update cursors if we have any

Closes #2308

See merge request GNOME/gtk!1249
2019-12-13 20:02:43 +00:00
Matthias Clasen
78227bf5b0 Merge branch 'matthiasc/for-master' into 'master'
some builder-tool improvements

See merge request GNOME/gtk!1248
2019-12-13 19:58:53 +00:00
Matthias Clasen
bf2c29a36a x11: Only update cursors if we have any
We were accessing an on-demand created hash table
without checking if it had been created first.

Fixes: https://gitlab.gnome.org/GNOME/gtk/issues/2308
2019-12-13 14:46:00 -05:00
Matthias Clasen
47285c6642 builder: Improve type name mangling
When looking for the get_type function for GThemedIcon,
try both g_themed_icon_get_type and gthemed_icon_get_type
The former is what gio has, the latter is still supported
to avoid breaking gweather_location_get_type.

Update tests to cover this new case.
2019-12-13 14:21:44 -05:00
Matthias Clasen
e4fb4116fd builder-tool: Don't try to find default boxed values
This doesn't work and yields an ugly, unnecessary
error message.
2019-12-13 14:21:44 -05:00
Matthias Clasen
6d3373cb2c gtk-builder-tool: More helpful error messages
Include line numbers in the error messages we
report, so it is possible to find the error.
2019-12-13 14:21:44 -05:00
Marek Kasik
6ddc214e68 printing: Fill device URI for non-Avahi printers
Device URI was not filled for non-Avahi printers by my previous commit.
I've added it back. It was a mistake during rebasing of the patch
to current master.
2019-12-13 17:53:14 +01:00
Matthias Clasen
91a802a1e5 Merge branch '1509-don-t-show-Rejecting-Jobs-when-we-don-t-know' into 'master'
Fix getting info for standalone IPP printers

Closes #1509

See merge request GNOME/gtk!1247
2019-12-13 16:13:17 +00:00
Daniel Mustieles
886ab54eda Updated Spanish translation 2019-12-13 12:24:36 +01:00
Matthias Clasen
4470e5bc93 gtk-demo: Some touchups
Make the theming style classes demo look a bit less odd.
2019-12-12 18:46:53 -05:00
Matthias Clasen
9bbacd3e4c Run gtk-builder-tool simplify over our ui files
This was done mainly to verify that the tool does not
make any unwarranted changes. The changes included here
are all cosmetic.
2019-12-12 18:37:39 -05:00
Matthias Clasen
353df67c0b Add GtkNative to the docs
It was not included in the generated docs.
2019-12-12 18:21:16 -05:00
Matthias Clasen
050eb9ba73 Fix up GtkBuilderScope docs
They were not hooked into the document generation.
2019-12-12 18:18:49 -05:00
Matthias Clasen
4fa5f5497a builder: Another small docs fix 2019-12-12 17:59:24 -05:00
Matthias Clasen
21a032b783 docs: Ignore more private headers 2019-12-12 17:59:24 -05:00
Matthias Clasen
207efd8932 docs: Remove symbols that no longer exist 2019-12-12 17:59:24 -05:00
Matthias Clasen
43c943e48a Merge branch 'issue-179' into 'master'
Use a separate gesture for middle clicks on PlaceView rows

Closes #179

See merge request GNOME/gtk!1199
2019-12-12 22:53:36 +00:00
Matthias Clasen
d6dc5da6db textbuffer: Minor doc fixes
Fix parameter name mismatches.
2019-12-12 17:31:13 -05:00
Matthias Clasen
12d787286e builder: Minor doc fixes
Fix parameter name mismatches.
2019-12-12 17:30:36 -05:00
Matthias Clasen
c33a7670d0 Merge branch 'wip/otte/builder' into 'master'
More builder work

Closes #2267

See merge request GNOME/gtk!1230
2019-12-12 20:36:08 +00:00
Matthias Clasen
bbb56d8216 Merge branch 'file-transfer' into 'master'
clipboard: file transfer portal support

See merge request GNOME/gtk!1244
2019-12-12 19:33:02 +00:00
Matthias Clasen
a20c8af678 clipboard: file transfer portal support
Implement file-list <-> application/vnd.flatpak.file-list
serialization by talking to the file transfer portal.

See https://github.com/flatpak/xdg-desktop-portal/pull/222
2019-12-12 14:25:33 -05:00
Matthias Clasen
0eb2b382a2 Merge branch 'master-gitlab-HC-tooltip' into 'master'
Set HighContrast tooltip back to black text over white background

See merge request GNOME/gtk!1242
2019-12-12 19:18:06 +00:00
Benjamin Otte
101298c54d gtk-demo: Don't include "gtk.h" 2019-12-12 19:50:55 +01:00
Benjamin Otte
f6bdfc32d3 tests: Set an existing font in testfontchooser 2019-12-12 19:50:55 +01:00
Benjamin Otte
5015730212 builder: Turn last dlsym() function into a scope API
Looking up a get_type function by its name is now also part of
GtkBuilderScope.
2019-12-12 19:39:36 +01:00
Benjamin Otte
f8a7f30a0d builder: Add GtkBuilderScope
GtkBuilderScope is an interface that provides the scope that a builder
instance operates in.
It creates closures and resolves types. Language bindings are meant to
use this interface to customize the behavior of builder files, in
particular when instantiating templates.

A default implementation for C is provided via GtkBuilderCScope (to keep
with the awkward naming that glib uses for closures). It is derivable on
purpose so that languages or extensions that extend C can use it.

The reftest code in fact does derive GtkBuilderCScope for its own scope
implementation that implements looking up symbols in modules.

gtk-widget-factory was updated to use the new GtkBuilderCScope to add
its custom callback symbols.
So it does it different from gtk-demo, which uses the normal way of
exporting symbols for dlsym() and thereby makes the 2 demos test the 2
ways GtkBuilder uses for looking up symbols.
2019-12-12 19:39:23 +01:00
Benjamin Otte
1f94028ff7 builder: Add gtk_builder_set_current_object()
Use it as the default object for expression binds and when connecting
signals. It is intended to work kind of as the "this" object while
parsing. In fact, the term "current object" was stolen from the Java
docs and various C++ tutorials for the this pointer.

Set the current object in gtk_widget_init_template() and
GtkListItemBuilder.

This more-or-less replaces the object passed to
gtk_builder_connect_signals() in GTK3.
2019-12-12 19:12:11 +01:00
Benjamin Otte
512c4c13a6 builder: Add gtk_builder_lookup_object()
... and use it. This function looks up an object like
gtk_builder_get_object() but generates an error on failure.

Unlike the evil function _gtk_builder_lookup_object() which also
generates an error but hides it for later lookup.

Use this to avoid continuing applying properties when an error was
encountered.
2019-12-12 19:12:11 +01:00
Benjamin Otte
552db7cb08 types: Move GTK_INVALID_LIST_POSITION here
I have no idea where it should go really - maybe glib?

It certainly shouldn't require everybody including selectionmodel code
just to get at this value.
2019-12-12 19:10:45 +01:00
Matthias Clasen
d564cb2a7e Merge branch 'terminal' into 'master'
imwayland: Suppport terminal purpose

See merge request GNOME/gtk!1243
2019-12-12 17:57:05 +00:00
Marek Kasik
a6e3fc2d2f printing: Fix getting info for standalone IPP printers
Create printer name from name of the advertised service
for standalone IPP printers as opposed to CUPS printers
advertised via Avahi which get name from their
resource path.
This is similar to what cups-filters does.

Pass GtkPrinter class to request for printer info
so that it does not need to be searched for
(such search could fail for standalone IPP printers).

https://gitlab.gnome.org/GNOME/gtk/issues/1509
2019-12-12 17:08:30 +01:00
Marek Kasik
e54049bc26 printing: Don't show Rejecting Jobs when we don't know
Set reasonable default values for printers discovered
by Avahi which do not have 'printer-type' attribute.
This is the case for network printers which were not
published by CUPS.

Related to the issue #1509.
2019-12-12 17:08:30 +01:00
Dorota Czaplejewicz
e331b39ca5 imwayland: Suppport terminal purpose 2019-12-12 14:37:51 +00:00
Jonathan Michalon
e6270ca43f Set HighContrast tooltip back to black text over white background
8abdbfee16 pulled Adwaita tooltip selectors,
but in the meantime the colors were also set to Adwaita's. Push back the same
behaviour as before because it's better for visually-impaired users.
2019-12-12 09:51:40 +01:00
Christoph Reiter
88da95d921 Merge branch 'honor-hotspot-gtk4' into 'master'
gdk/x11: Honor hotspot during drag cancel animation

See merge request GNOME/gtk!1236
2019-12-11 12:59:23 +00:00
Chun-wei Fan
44f9c67466 Merge branch 'vulkan-no-layered-windows' into 'master'
Win32: Do not enable layered windows when using Vulkan

See merge request GNOME/gtk!1217
2019-12-11 06:24:49 +00:00
Matthias Clasen
02bbe399df Merge branch 'matthiasc/for-master' into 'master'
widget factory: Fix more grid layout fallout

See merge request GNOME/gtk!1237
2019-12-10 03:05:09 +00:00
Matthias Clasen
41bb40feee widget factory: Fix more grid layout fallout 2019-12-09 21:29:03 -05:00
Benjamin Otte
336d652be5 a11y: We can peek here
Avoids instantiating a11y objects when we don't need to.
2019-12-09 16:35:41 +01:00
Benjamin Otte
d3e8678955 treeview: Don't create a cyclic reference
TreeRowReference refs the proxy object, so don't use proxies.
2019-12-09 16:35:41 +01:00
Benjamin Otte
503d988c1b label: Compute label baselines correctly
When we were switching smallest and widest, we were not switching the
baselines.
2019-12-09 16:35:41 +01:00
Robert Mader
7a46378e71 gdk/x11: Honor hotspot during drag cancel animation
Otherwise the icon "jumps" to the cursor position with its top left when
the animation starts.
This is especially visible if the dragged item is big, like when dragging
mails in Thunderbird.
2019-12-09 01:45:30 +01:00
Matthias Clasen
9f6d12551f Add GtkTreeListRow type to the docs 2019-12-08 17:58:09 -05:00
Matthias Clasen
43c93d6f85 Add missing listmodel and selection types to the docs 2019-12-08 13:56:47 -05:00
Matthias Clasen
d683d085c0 tree list model: Add a missing annotation
The GtkTreeListModelCreateModelFunc returns
a new reference.
2019-12-08 00:30:32 -05:00
Matthias Clasen
92ab450983 inspector: Avoid critical warnings
We were still using this but it's not defined in the UI xml.

Fixes: https://gitlab.gnome.org/GNOME/gtk/issues/2295
2019-12-07 19:39:02 -05:00
Matthias Clasen
7b14c65b41 Merge branch 'inspector-display' into 'master'
Inspector display

See merge request GNOME/gtk!1234
2019-12-07 23:20:51 +00:00
Matthias Clasen
c89c652401 inspector: Make the css tree respect inspected display
The display is used here to force reparsing the theme
on the right settings object.
2019-12-07 18:07:44 -05:00
Matthias Clasen
f0f57d156b inspector: Make logs respect inspected display 2019-12-07 18:07:05 -05:00
Matthias Clasen
cecf4f2763 inspector: Make inspect button use inspected display
This may not matter, but just for cleanliness.
2019-12-07 18:07:05 -05:00
Matthias Clasen
4eeed47c7b inspector: Make general respect inspected display 2019-12-07 18:07:05 -05:00
Matthias Clasen
bd1f7e057a inspector: Make visual settings respect the inspected display
This is not quite complete, GTK and GSK debug flags
are not per display, and slowdown and text direction
are not either.
2019-12-07 18:07:05 -05:00
Matthias Clasen
174d8b72a5 inspector: Make css editor respect inspected display
Stop using gdk_display_get_default and use the
inspected display instead.
2019-12-07 18:07:05 -05:00
Matthias Clasen
1437b0856c inspector: Make object tree respect inspected display
Stop using gdk_display_get_dfault and use the
inspected display instead.
2019-12-07 14:59:49 -05:00
Matthias Clasen
917181cb67 window: Get rid of the inspector_window static
Use the new per-display inspector plumbing and
stop relying on a static variable.
2019-12-07 14:59:49 -05:00
Matthias Clasen
a207a4b3cd inspector: Attach inspector window to display
Give the inspector window a ::inspected-display
property, and pass a display when obtaining an
inspector window. Update the caller.
2019-12-07 14:59:49 -05:00
Matthias Clasen
39a1d27960 window: Inspector cleanups
Reduce the use of the inspector_window static.
The goal is to have one inspector window per
display, so we need to get rid of the static.
2019-12-07 14:59:49 -05:00
Matthias Clasen
5ef4a64084 window: Remove inspector updating fully
Commit 05e752e096 left some ruins behind.
Clean that up.
2019-12-07 14:59:49 -05:00
Matthias Clasen
baacd9efbf inspector: Init yourself
No need to have GTK call this from the outside.
2019-12-07 14:59:49 -05:00
Matthias Clasen
abde37a4d7 inspector: Cleanup
Remove an unused enum.
2019-12-07 14:59:49 -05:00
Matthias Clasen
3ee9b0cf4b Make a test with a custom display
This completely breaks the inspector.
2019-12-07 10:03:42 -05:00
Matthias Clasen
88049915a2 Merge branch 'doc-update' into 'master'
doc: Cleanup doc removing mentions of gdk_surface_shape_combine_region()

See merge request GNOME/gtk!1232
2019-12-05 22:11:31 +00:00
Hubert Figuière
585397937d doc: Cleanup doc removing mentions of gdk_surface_shape_combine_region() 2019-12-05 11:33:09 -05:00
Matthias Clasen
256b6f1aff Merge branch 'matthiasc/for-master' into 'master'
fix leaks in the testsuite

See merge request GNOME/gtk!1231
2019-12-05 00:01:23 +00:00
Matthias Clasen
acabdafb35 Fix treelistmodel tests
They were failing to return a reference where they
need to. This was uncovered by fixing an unrelated
ref leak.
2019-12-04 18:30:37 -05:00
Matthias Clasen
168c1f440d Fix leaks in tests
All the list model tests were leaking items,
because g_list_model_get_item is transfer full.

Fixing these unveils a crash in the treelistmodel
and maplistmodel tests.
2019-12-04 18:24:56 -05:00
Tim Sabsch
33a8ef4bce Update German translation 2019-12-04 19:37:01 +00:00
Benjamin Otte
33bd8f322c builder: Improve error message 2019-12-03 18:12:25 +01:00
Benjamin Otte
bfe4255807 builder: Allow objects in gtk_builder_value_from_string_type()
Instead of throwing an error, lookup objects with
gtk_builder_get_object().
2019-12-03 18:12:25 +01:00
Benjamin Otte
a15fb95c46 gtk-demo: Use normal way to lookup up symbols
We're a normal application, so we can use the normal way to hook up code
into builder files, which is using dlsym() for the function pointers.

There's no need to to extra work exporting static symbols.
2019-12-03 18:12:25 +01:00
Benjamin Otte
292371932b css: Handle invalid :not() selectors
We weren't correctly ending the ( ) block when encountering an error.

Testcases added.

Fixes #2281
2019-12-03 18:12:25 +01:00
Timm Bäder
564e8f483c Merge branch 'wip/wayland-hidpi-swap-region' into 'master'
Fix HiDPI swap regions on Wayland

See merge request GNOME/gtk!1228
2019-12-03 16:05:08 +00:00
Jonas Ådahl
ba74f41a70 wayland/vulkancontext: Fix present region on HiDPI
VkPresentRegionsKHR is expected to operate in buffer coordinates, but
the region we get passed is in surface coordinates, so it must be scaled.
2019-12-03 16:45:37 +01:00
Jonas Ådahl
d6a6313493 wayland/glcontext: Fix damage region on HiDPI
The passed regions are in surface coordinates, but
eglSwapBuffersWithDamage() is in buffer coordinates.
2019-12-03 16:45:37 +01:00
Emmanuele Bassi
9b5a7ae802 Merge branch 'fix-treemodelsort_processed_as_treemodel' into 'master'
Annotate GtkTreeModelSort.new_with_model() appropriately

See merge request GNOME/gtk!1134
2019-12-03 15:36:43 +00:00
LutzLue
e4b8481dd0 Annotate GtkTreeModelSort.new_with_model() appropriately
The new_with_model() method is a constructor, and it returns a GtkTreeModelSort
instance, even if the C API returns a GtkTreeModel for the convenience of C
developers.

Fixes: #1077
2019-12-03 15:36:42 +00:00
Timm Bäder
d868b23c76 gl renderer: Implement blurred inset shadow nodes
And with this...

Fixes #1101
2019-12-03 08:40:35 +01:00
Timm Bäder
56b456ff21 gl renderer: Remove unused uniform from inset shadow shader 2019-12-03 08:40:35 +01:00
Timm Bäder
b91913d10d opbuffer: Remove unused op member 2019-12-03 08:40:35 +01:00
Timm Bäder
ac1497eb2d testsuite: Add an inset shadow rendering test case 2019-12-03 08:40:35 +01:00
Timm Bäder
1854f3f49c gl renderer: Cache current scale in RenderOpBuilder
We call ops_get_scale a lot, so this should be better. It will also make
a later x/y split for the scaling easier.
2019-12-03 08:40:34 +01:00
Timm Bäder
a75523da68 cssshadowvalue: Simplify inset shadow nodes to color nodes if possible
inset shadows like this are frequently used to implement highlights in
CSS without crowing them min size of the element.
2019-12-03 08:40:34 +01:00
Timm Bäder
ca66e9788c gl renderer: Save one level of indentation 2019-12-03 08:40:34 +01:00
Timm Bäder
83ec7d562a window: Don't set invalid csd input shape
This might happen if the CSS values of the decoration node are broken,
e.g. if people *accidentally* type large negative values for the
margins.

Fixes #2268
2019-12-03 08:40:34 +01:00
Timm Bäder
05e9a9b572 snapshot: Reorder color matrix nodes containing a transform node
A color matrix node that contains a transform node can also be expressed
the other way around, as a transform node containing a color matrix
node.

In the general case, the color matrix node will have to draw its
child to a texture so it can color every pixel of that texture, but the
renderers can short-cut this if the child of the color matrix node is
already a texture node. So if we have a node tree like

Color Matrix
    - Transform
        - Texture

The renderer would have to either check the grandchild of the color
matrix or simply fall back to rendering the transform node to a texture.

In the new configuration:

Transform
    - Color Matrix
        - Texture

The renderer can easily see that the child node of the color matrix node
is a texture, and skip rendering it to a texture.

This is for example happening in current Adwaita for spinners, which are
rotated symbolics.
2019-12-03 08:40:34 +01:00
Timm Bäder
bc7b37d307 snapshot: Factor out color matrix merging
We will use that elsewhere in the next commit.
2019-12-03 08:40:34 +01:00
Timm Bäder
fb5dc73841 gl renderer: Implement blurred shadow nodes 2019-12-03 08:40:34 +01:00
Timm Bäder
8d61d9f627 gl renderer: Take a TextureRegion in blur_texture
So we can refer to textures on a texture atlas.
2019-12-03 08:40:34 +01:00
Timm Bäder
22b6085c32 gl renderer: Scale blur radius
We scale the texture size, so as a consequence we have to scale the blur
radius.
2019-12-03 08:40:34 +01:00
Timm Bäder
2deb1a05a0 gl renderer: Add some often needed debug code 2019-12-03 08:40:34 +01:00
Timm Bäder
8ca46169b1 gl renderer: Blur shader improvements
Use a two-pass blur shader, fix a few other things and unify the
blurring of blur nodes and blurred outset shadow nodes.

Related to #1283
2019-12-03 08:40:34 +01:00
Timm Bäder
642ced0cfc testblur: Fix default blur radius
sync it up with the adjustment value. also just add the destroyed
handler.
2019-12-03 08:40:34 +01:00
Matthias Clasen
a635076106 Merge branch 'improve-popover-menu-style' into 'master'
Adwaita: Improve popover.menu styling

See merge request GNOME/gtk!1083
2019-12-02 13:19:50 +00:00
nana-4
23d8aa40fe Adwaita: Remove unused popover check/radio styling 2019-12-02 20:48:10 +09:00
nana-4
0933630ee5 Adwaita: Flatten circular buttons in popover.menu
Just reuse the list button style.

https://gitlab.gnome.org/GNOME/gtk/issues/1824
2019-12-02 20:48:09 +09:00
nana-4
797cecd9ae Adwaita: Make check & radio symbolic icon style in popover.menu
The disabled modelbutton color needs to be specified explicitly
in order for check & radio to properly read the color with
currentColor.

https://gitlab.gnome.org/GNOME/gtk/issues/1824
2019-12-02 20:48:09 +09:00
nana-4
4c2707916c Adwaita: Improve popover.menu styling
Based on the mockup:
https://gitlab.gnome.org/Teams/Design/os-mockups/blob/master/menus/menu-design-patterns.png

- Remove horizontal padding from popover.menu contents
- Remove roundness from modelbutton
- Adjust sizing to match the mockup
- Fix visual glitches on button.image-button.model
- Add missing mergin to arrow icons
- Fix accelerator position in rtl direction
- Fix accelerator color

https://gitlab.gnome.org/GNOME/gtk/issues/1824
2019-12-02 20:48:09 +09:00
Matthias Clasen
ab32b1bba2 Merge branch 'wip/muktupavels/opaque-region-master' into 'master'
window: fix opaque region

See merge request GNOME/gtk!1222
2019-12-01 15:11:00 +00:00
Matthias Clasen
619c892032 Merge branch 'sass-no-extend-compound-master' into 'master'
themes: remove various @extend with compound selectors

See merge request GNOME/gtk!1223
2019-12-01 15:09:39 +00:00
nana-4
87ea0253aa themes: remove various @extend with compound selectors
They are no longer supported by sass and broken with libsass 3.6.3
(https://github.com/sass/libsass/issues/3033)

This removes them by replacing them with a placeholder selector. This at
least brings the resulting CSS size down a bit so gtk can be build
again.

`%button.flat.suggested-action` has been replaced by
`%selection_mode_button_flat`, which is a more appropriate selector for
`.selection-mode button.titlebutton`.

The CSS was generated with libsass 3.5.5.

Co-authored-by: Christoph Reiter <reiter.christoph@gmail.com>

See https://gitlab.gnome.org/GNOME/gtk/issues/2237
2019-12-01 10:43:16 +09:00
Alberts Muktupāvels
e81a90c432 window: fix opaque region
Decoration node for drawing is used only for client side decorated
windows, but corners from opaque region is subtracted also for
normal windows.

Rename function to better reflect what it does and do not subtract
corners if decoration node was not used for drawing.
2019-11-30 20:19:26 +02:00
Timm Bäder
fe385c28f6 Merge branch 'gtk-link-color' into 'master'
Adwaita: always use link specific colors for link selector

See merge request GNOME/gtk!1201
2019-11-30 07:40:48 +00:00
Matthias Clasen
6c4ab7d208 Merge branch 'matthiasc/for-master' into 'master'
some builder-tool tests

See merge request GNOME/gtk!1220
2019-11-29 15:21:40 +00:00
Matthias Clasen
dd52dd8bb0 Update the test scripts
All tools got renamed to have a gtk4 prefix.
2019-11-29 10:06:39 -05:00
Matthias Clasen
174cdb09a7 Add a test for the previous fix 2019-11-29 10:04:59 -05:00
Matthias Clasen
c3ca34cf51 Merge branch 'matthiasc/for-master' into 'master'
builder-tool: Fix handling of layout properties

See merge request GNOME/gtk!1219
2019-11-29 14:00:05 +00:00
Matthias Clasen
85950afbbd builder-tool: Fix handling of layout properties
We were not properly identifying layout properties
that need to be kept, causing GtkGrid left-attachment
to go missing in widget-factory.ui.
2019-11-29 08:47:35 -05:00
Matthias Clasen
da063a8aa5 Fix up widget-factory ui 2019-11-29 08:34:09 -05:00
Timm Bäder
9d94627f75 Merge branch 'dont-color-labels-directly-gtk4' into 'master'
Adwaita: Avoid directly coloring labels wherever possible (GTK4)

Closes #1643

See merge request GNOME/gtk!1209
2019-11-29 11:53:07 +00:00
Timm Bäder
5bdd25627f reftests: Fix css-multi-state test
Properly unset theme CSS and use the right selector for the toggle
buttons.
2019-11-29 20:26:45 +09:00
Carlo Lobrano
7bb8a480f1 Adwaita: always use link specific colors for link selector
link target uses `$selected_bg_color` and `$selected_fg_color` for the
definition of some selectors (e.g. selected).

While `$link_color` and `$link_visited_color` are based on
`$selected_bg_color`, this does not seem coherent.

Replacing `$selected_*g_color` in link target style with link colors
defined in `_colors.scss file`.
2019-11-29 07:32:16 +01:00
Matthias Clasen
be74be0e3b widget-factory: Fix a popover menu
This one is manually constructed, and things have
changed enough for that to break. Fix it up.
2019-11-27 17:41:44 -05:00
Timm Bäder
982890515d gl renderer: Don't use g_assert() for code that should always run
g_assert can be compiled out.
2019-11-27 16:56:47 +01:00
Timm Bäder
1817025f46 gl renderer: Don't save repeat nodes to disk
This is just debuggin code someone forgot.
2019-11-27 16:47:14 +01:00
Matthias Clasen
c5d24fc5cd Merge branch 'single-compilation-symbol' into 'master'
Use a single compilation symbol

See merge request GNOME/gtk!1216
2019-11-27 15:14:54 +00:00
Timm Bäder
965e37bee9 Merge branch 'fix-issue-1646-master' into 'master'
HighContrast: Add missing color to entry

Closes #1646

See merge request GNOME/gtk!1215
2019-11-27 13:52:08 +00:00
Emmanuele Bassi
def700739d Use a single compilation symbol
We use a compilation symbol in our build to allow the inclusion of
specific headers while building GTK, to avoid the need to include only
the global header.

Each namespace has its own compilation symbol because we used to have
different libraries, and strict symbol visibility between libraries;
now that we have a single library, and we can use private symbols across
namespaces while building GTK, we should have a single compilation
symbol, and simplify the build rules.
2019-11-27 13:33:43 +00:00
nana-4
5590bcb9cc HighContrast: Add missing color to entry
So entries don't inherit color from the parent element anymore.

Fixes https://gitlab.gnome.org/GNOME/gtk/issues/1646
2019-11-27 22:22:11 +09:00
Timm Bäder
9f69c7f3e8 Merge branch 'broken-annotation' into 'master'
builder: Fix broken annotation

See merge request GNOME/gtk!1213
2019-11-27 06:46:15 +00:00
Robert Ancell
0df45f0de0 builder: Fix broken annotation
Missing a ':', was introduced in 0627bba5a0.
2019-11-27 16:06:36 +13:00
Chun-wei Fan
9c5ea8eba4 gdkvulkancontext-win32.c: Suppress layered Windows on Vulkan
The Vulkan renderer does not work well with layered windows enabled, so
turn it off when we successfully created the Vulkan context on Windows.
2019-11-26 17:00:11 +08:00
Timm Bäder
8f6de1f955 gl renderer: Load flipped-y offscreen vertex data directly
Instead of loading the unflipped version first and then flipping it.
Don't do it in add_render_ops either but only in the function actually
adding the render ops for the nodes, since those frequently have
early-out conditions that don't need the vertex data at all.
2019-11-26 09:09:25 +01:00
Timm Bäder
4f532224e0 testsuite: Add another repeat node test case 2019-11-26 09:09:25 +01:00
Timm Bäder
1c2661ed12 gl renderer: Fix repeat node shader once again 2019-11-26 09:09:25 +01:00
Timm Bäder
91f7ac2d58 gl renderer: Care more about 0×0 offscreen nodes
These never result in a rendering of course, but we must make sure not
to create a 0×0 texture for them, since that will cause problems later
on.
2019-11-26 09:09:25 +01:00
Timm Bäder
3d1a9c7484 Merge branch 'unsafe-strdup-printf' into 'master'
gtk-demo: Fix incorrect use of g_strdup_printf

See merge request GNOME/gtk!1211
2019-11-26 07:11:19 +00:00
Robert Ancell
25e4174a38 gtk-demo: Fix incorrect use of g_strdup_printf
Was broken in a refactoring in 4a2f313
2019-11-26 10:11:28 +13:00
Emmanuele Bassi
04bb5aad36 Use a separate gesture for middle clicks on PlaceView rows
The click gesture in GtkListBox is exclusively for primary button
clicks; this means we're never going to get a click from the middle
button. We need to use a separate GtkGestureClick controller for middle
clicks, in order to activate rows with the 'open-in-tab' flag.

Fixes: #179
2019-11-25 16:02:40 +00:00
nana-4
4f82a0de89 Adwaita: Avoid directly coloring labels wherever possible
Directly coloring labels can create a lot of unintended behaviors.
Unfortunately we can't avoid directly coloring `label:disabled` because
it can be used individually. This, however, tries to inherit color from
the parent element of labels wherever possible.

Fixes https://gitlab.gnome.org/GNOME/gtk/issues/1643
2019-11-26 00:39:33 +09:00
Benjamin Otte
9e4901e8ce testsuite: Fix expected test output
This reverts part of 91497348bf
2019-11-23 19:33:36 +01:00
Benjamin Otte
7523a3f2f2 cssprovider: Don't add empty rulesets
This change was lost during the parser changes, but the newly added test
exposes it.

And fix the expected error, the syntax has changed.
2019-11-23 19:02:36 +01:00
Alexandr Miloslavskiy
fd1630e049 Fix crash in parse_border()
The bug was introduced in commit:
	9b7640b8 by Benjamin Otte, 2012-03-26 17:24:02
	styleproperty: Make _gtk_style_property_parse_value() return a CssValue

In that commit, `values` changed from `GValue*` to `GtkCssValue**`,
but one `!G_IS_VALUE (&values[8])` was left untouched. As a result,
if `border` shorthand contains anything after color, it might crash,
depending on memory layout.

New test included.

Fixes: #751
2019-11-23 18:15:19 +01:00
Benjamin Otte
e3c3cbbbcb Merge branch 'wip/otte/builder' into 'master'
Reorganize various GtkBuilder things

See merge request GNOME/gtk!1204
2019-11-23 17:09:15 +00:00
Benjamin Otte
4fbb0d7ce4 builder: Make the struct private
We don't want anyone to subclass it - if we want to allow bindings to
extend GtkBuilder, we will be using delegate objects/functions for it.
2019-11-22 17:42:32 +01:00
Benjamin Otte
245fdc8b38 builder: Remove get_type_from_name() vfunc 2019-11-22 17:42:32 +01:00
Benjamin Otte
420169d5cd builder: Improve signal connecting
- Propagate the error back to the parser, so we get a proper GError
  instead of a g_warning().
- Connect closures by id, don't construct a name from the ids so that
  glib can take it apart again.
2019-11-22 17:42:31 +01:00
Benjamin Otte
b025ee428c builder: Connect signals automatically
gtk_builder_connect_signals() is no longer necessary, because all the
setup that made it necessary to have this extra step is now done
automatically via the closure functions.
2019-11-22 17:42:31 +01:00
Benjamin Otte
82395a93b0 reftests: Switch to gtk_builder_set_closure_func() 2019-11-22 17:42:31 +01:00
Benjamin Otte
b7ff017f8d widget: Change templates to use closure functions
... instead of connect functions.
2019-11-22 17:42:31 +01:00
Benjamin Otte
0627bba5a0 builder: Add gtk_builder_set_closure_func()
This allows bindings and templates to setup a way to create closures.
2019-11-22 08:13:16 +01:00
Benjamin Otte
ab53731f4a widget: Reinstate custom closure func
It turns out it ws used in various places.
2019-11-22 07:46:18 +01:00
Benjamin Otte
094c537001 builder: Add gtk_builder_create_closure()
This will be the future way to connect signals automatically (and be
used for other things, too).

For now, gtk_builder_connect_signals_default() is ported to use it.
2019-11-22 07:46:18 +01:00
Benjamin Otte
27d05102ab builder: Remove user_data argument from gtk_builder_connect_signals()
This is pretty unused and gets in the way of the next steps.

A potential side effect is that for templates the widget was passed as
the user data argument. If that turns out to be important, we have to
special case that situation.
2019-11-22 07:46:18 +01:00
Benjamin Otte
f5e4dc824c builder: Remove application setter/getter
It's unused and doesn't belong to GtkBuilder.
2019-11-22 07:46:18 +01:00
Benjamin Otte
80acc8f296 builder: Carry the module as part of the GtkBuilder object
This way, we don't open the module in every place we want to look up
functions.
2019-11-22 07:46:18 +01:00
Benjamin Otte
e3860d25e9 builder: Fix typo in docs 2019-11-22 07:35:03 +01:00
Benjamin Otte
a2634077e7 testsuite: Print useful statement on notify test error
... and don't instantly abort, test the rest of the properties, too.
2019-11-22 07:35:03 +01:00
Benjamin Otte
c72c0f4d43 types: Remove and unused typedef
GtkRcPropertyParser is gone.
2019-11-22 07:35:03 +01:00
Benjamin Otte
d92cfa2179 settings: Remove RC property parsers
They've not been used for a long time and the APIs where they could
reasonably be used have been gone for as long.
2019-11-22 07:35:03 +01:00
Benjamin Otte
bbdaa4a0ff settings: Remove code dealing with property parsers
They only remained in private code where they were always set to NULL.
2019-11-22 07:35:03 +01:00
Sam Hewitt
5e11a2ae6a adwaita: level bar refinements
- shave a few pixels off large level bar
 - thinner discrete level bar
2019-11-19 11:46:18 -05:00
Timm Bäder
053360df85 gl renderer: Remove unused function 2019-11-19 11:06:08 +01:00
Timm Bäder
39a48de025 testsuite: Add a testcase for repeat nodes that don't repeat 2019-11-19 10:45:35 +01:00
Timm Bäder
600ce68210 gl renderer: Add a short cut for repeat nodes that don't repeat
These happen and we don't even need to draw the child to a texture.
2019-11-19 10:45:02 +01:00
Timm Bäder
604f44da11 gl renderer: Fix repeat nodes that don't repeat
Fixes #2234
2019-11-19 10:31:21 +01:00
Timm Bäder
581f5bd749 csstokenizer: Plug a leak 2019-11-19 09:37:45 +01:00
Timm Bäder
ecc40cf115 rendernodeparser: Only report a GError* if we have one 2019-11-19 09:37:26 +01:00
Timm Bäder
3d7817154c rendernodeparser: Handle resolving NULL urls 2019-11-19 09:37:03 +01:00
Emmanuele Bassi
232e313823 docs: Add migration note for iconify → minimize
See commit b70e4f6de9.
2019-11-18 14:12:41 +00:00
Daniel Mustieles
914e2a6656 Updated Spanish translation 2019-11-18 15:08:59 +01:00
Emmanuele Bassi
9a88d17ef2 Merge branch 'gdk-backend-imports' into 'master'
Correct Gdk backend import paths and related gtk-doc

See merge request GNOME/gtk!1197
2019-11-18 10:27:32 +00:00
Andy Holmes
907a86fd93 Correct Gdk backend import paths and related gtk-doc
Correct the paths in the include guard warnings and use the `@Include`
directive for the Gdk backends.
2019-11-18 00:31:38 -08:00
Matthias Clasen
d4180931f8 Merge branch 'seal-popover-menu' into 'master'
Privatize popover menu pieces

See merge request GNOME/gtk!925
2019-11-18 01:57:55 +00:00
Matthias Clasen
dd913423d3 Merge branch 'signal-naming' into 'master'
gtkstyleprovider: Rename -gtk-style-changed signal to have a valid name

See merge request GNOME/gtk!1176
2019-11-18 01:55:34 +00:00
Matthias Clasen
c296101a2f Merge branch 'issue-67' into 'master'
Rename "iconify" to "minimize"

Closes #67

See merge request GNOME/gtk!1190
2019-11-18 00:52:53 +00:00
Emmanuele Bassi
1ba2923616 Merge branch 'meson-bump' into 'master'
Bump up the required version of Meson

See merge request GNOME/gtk!1191
2019-11-16 20:26:31 +00:00
Emmanuele Bassi
1ec4cb7f17 Disable GdkSurface.minimize on Wayland
The existing xdg-shell protocols do not support minimization in a way
that allows us to implement the GdkSurface API; the only minimization
operation does not come with a state notification, nor it comes with
a way to undo itself.

Closes: #67
2019-11-16 20:25:01 +00:00
Emmanuele Bassi
b70e4f6de9 Rename "iconify" to "minimize"
The "iconified" state is mostly an X11-ism; every other platform calls
this state "minimized" because it may not involve turning a window into
an icon at all.
2019-11-16 20:07:37 +00:00
Emmanuele Bassi
3c11c57755 Bump up the required version of Meson
Match the one we're testing on our CI infrastructure.
2019-11-16 18:40:23 +00:00
Emmanuele Bassi
1b7c6e5687 Merge branch 'gdkx-import-doc' into 'master'
Correct GdkX11 import path in docs and include guards

Closes #2254

See merge request GNOME/gtk!1188
2019-11-16 18:19:26 +00:00
Andy Holmes
d32cd210bb Correct GdkX11 import path in docs and include guards
Update the include directives in the documentation, as well as the
include guards in headers, to point to gdk/x11/gdkx.h.

closes #2254
2019-11-16 01:35:09 -08:00
Emmanuele Bassi
e056e4ff58 Merge branch 'fix-menu-check-radio-styling-gtk4' into 'master'
Adwaita: Fix check/radio styling in menu (GTK4)

See merge request GNOME/gtk!1187
2019-11-15 23:26:17 +00:00
Emmanuele Bassi
ae66c07a70 Merge branch 'dont-hardcode-shared-library' into 'master'
build: Don't hardcode shared_library() in meson

See merge request GNOME/gtk!1172
2019-11-15 23:24:42 +00:00
Niklas Hambüchen
3936412332 Try building static libs on CI 2019-11-15 18:42:36 +01:00
nana-4
ea5eeb7c7a Adwaita: Fix check/radio styling in menu
The new check/radio style increased their specificity, but it was not
synchronized in the menu styling.

This commit increases the specificity to match the updated check/radio
styling.

https://gitlab.gnome.org/GNOME/gtk/issues/2096
2019-11-16 01:08:44 +09:00
Emmanuele Bassi
767df50eda Merge branch 'building-docs' into 'master'
Document the use of build types when configuing GTK

See merge request GNOME/gtk!1113
2019-11-15 13:05:39 +00:00
Emmanuele Bassi
baae2920dc Merge branch 'Master_checkradio_refresh' into 'master'
Refresh check/radio styling, ported from gtk3

See merge request GNOME/gtk!1175
2019-11-15 12:36:12 +00:00
frederik.feichtmeier
832419b2c3 Refresh check/radio styling, ported from gtk3 2019-11-15 13:16:07 +01:00
Emmanuele Bassi
ff78adb25d Merge branch 'fix-emoji-picker-styling' into 'master'
Adwaita: Fix emoji picker styling (GTK4)

See merge request GNOME/gtk!1181
2019-11-14 16:30:49 +00:00
nana-4
e05f404fc5 Adwaita: Fix emoji picker styling
- Adjust the emoji picker appearance to be the same as gtk3's.
- Fix button.emoji-section margins in RTL.
- Prevent the .emoji hover effect from being applied to the entire
  nested popover.
2019-11-15 00:04:18 +09:00
Kjell Ahlstedt
d572b5d94c headerbar: Disconnect signal handlers when children are removed
The signal handler that calls notify_child_cb() is disconnected
from a child widget before the child is removed from the header bar.
gtk_header_bar_dispose() chains up before destroying the start and end
boxes, thus avoiding calls to notify_child_cb() after start_box and
end_box have been cleared.

Fixes #2246
2019-11-14 09:15:58 +01:00
Timm Bäder
c2306d3ba6 inspector: Select an object when activating it 2019-11-14 09:15:58 +01:00
Timm Bäder
edf56b438e css: short-circuit gtk_css_dimension_value_try_add
No need to allocate a new css value for something that we already have,
because one of the two values is 0
2019-11-14 09:15:58 +01:00
Timm Bäder
cd3cd64769 cssdimenstionvalue: Add common degree value singletons 2019-11-14 09:15:58 +01:00
Timm Bäder
fb0b0ddfe0 cssdimensionvalue: Add 50% singleton
Also pretty common
2019-11-14 09:15:58 +01:00
Timm Bäder
3180cdb9ef cssdimensionvalue: Add more common pixel values
These are used for icon sizes, etc.
2019-11-14 09:15:58 +01:00
Timm Bäder
07d1ea4356 cssimagerecolor: Avoid copying colors 2019-11-14 09:15:58 +01:00
Timm Bäder
e5f1ff6a4d popover: Use a bin layout for the contents gizmo 2019-11-14 09:15:58 +01:00
Timm Bäder
f8303c7a22 testpopover: Plug two GtkBuilder leaks 2019-11-14 09:15:58 +01:00
Timm Bäder
af6d1839e1 Merge branch 'wip/christopherdavis/issue-2233' into 'master'
Adwaita: remove unwanted spacing for boxes as titlebars

Closes #2233

See merge request GNOME/gtk!1177
2019-11-13 14:29:01 +00:00
Christopher Davis
b4b7fe122e Adwaita: remove unwanted spacing for boxes as titlebars
A GtkBox in a titlebar could have unwanted spacing.
This caused a glitch in split-header applications where
parts of the titlebar would be transparent or black.

This commit tweaks Adwaita to make sure no spacing is added for boxes when used as titlebars.

Fixes #2233
2019-11-13 06:19:05 -08:00
Timm Bäder
e36940fa8c Merge branch 'master.msvc.fix' into 'master'
gtk/gtkcssrgbavalue.c: Fix build on Visual Studio

See merge request GNOME/gtk!1178
2019-11-13 10:40:02 +00:00
Chun-wei Fan
d2e13dd3e4 gtk/gtkcssrgbavalue.c: Fix build on Visual Studio
Visual Studio does not allow static or global structures to use
static storage duration by compound literals, which is actually a
GCCism[1].

[1]: See https://gcc.gnu.org/onlinedocs/gcc/Compound-Literals.html
2019-11-13 18:08:15 +08:00
Philip Withnall
13f4d639fd gtkstyleprovider: Rename -gtk-style-changed signal to have a valid name
Signal names must start with a letter. They can’t start with a hyphen.

It was originally added in commit 74f4c6f6bd with no given reason
for why the signal name was chosen as it was.

Signed-off-by: Philip Withnall <withnall@endlessm.com>
2019-11-12 19:51:33 +00:00
Emmanuele Bassi
ad48bbb849 Merge branch 'issue-2230' into 'master'
Add GtkCss API to the introspection data

Closes #2230

See merge request GNOME/gtk!1173
2019-11-11 16:11:06 +00:00
Emmanuele Bassi
2497d982b0 Add GtkCss API to the introspection data
Some of the CSS API has been moved to a public namespace, so we need to
include it into the introspection data we build in order for people to
use it.

Fixes: #2230
2019-11-11 15:53:09 +00:00
Niklas Hambüchen
bb9c07d8fe build: Don't hardcode shared_library() in meson.
Instead, use the standard library().
This is a meson best practice.

Fixes -Ddefault_library=static not having any effect.
2019-11-11 16:37:46 +01:00
Emmanuele Bassi
ace2208f45 docs: Rename SGML files
We've been using XML for ages.
2019-11-11 13:52:08 +00:00
Emmanuele Bassi
b8c4009686 docs: Fix the XML indentation 2019-11-11 13:52:08 +00:00
Emmanuele Bassi
6f0ff3a8cb docs: We run meson, not configure 2019-11-11 13:52:08 +00:00
Emmanuele Bassi
209e8b54e9 docs: Add a section on supported build types
GTK uses the Meson `buildtype` option to determine whether to enable or
disable debugging code and safeties. We should document our behaviour
and expectations.
2019-11-11 13:52:08 +00:00
Matthias Clasen
bfa0509f08 Privatize popover menu pieces
Don't allow manual creation of popover menus
anymore. This lets us also make GtkModelButton
private
2019-11-11 12:42:06 +01:00
Piotr Drąg
07d17c5bc1 Update Polish translation 2019-11-10 12:45:22 +01:00
Daniel Mustieles
e26c361d2d Updated Spanish translation 2019-11-08 12:44:39 +01:00
Timm Bäder
290e250886 Merge branch 'adwaita-emoji-picker-adjustments-gtk4' into 'master'
Adwaita: Emoji picker adjustments

See merge request GNOME/gtk!1160
2019-11-07 11:56:17 +00:00
Alex Monday
22d5b9bc41 Adwaita: Emoji picker adjustments
- Add margins for search entry;
- Increase side margins for emoji-section buttons box;
- Apply border-radius on hovered emoji;
- Adjust indication of hovered emoji-section button.
2019-11-06 18:41:11 +05:00
Benjamin Otte
ab407ba57c Merge branch 'kill-entry-buffer-demo' into 'master'
gtk-demo: Drop the entry buffer demo

See merge request GNOME/gtk!1166
2019-11-05 19:08:22 +00:00
Benjamin Otte
07f2024bfc scrolledwindow: Use dispose(), not destroy() 2019-11-05 20:06:44 +01:00
Benjamin Otte
accbfc0083 Merge branch 'wip/chergert/textundo' into 'master'
Add undo/redo support for GtkTextView, GtkText, and GtkEntry

See merge request GNOME/gtk!1158
2019-11-05 18:52:25 +00:00
Matthias Clasen
e8d890ae0c gtk-demo: Drop the entry buffer demo
We all agree that entry buffers are not something
we should promote in demos.
2019-11-05 18:50:06 +00:00
Christian Hergert
bfc1e77b7f migration: add GtkEntryBuffer::deleted-text to migration guide 2019-11-05 10:27:29 -08:00
Christian Hergert
dba9298c14 gtk-demo: set irreversable actions for textview demos 2019-11-05 10:27:29 -08:00
Christian Hergert
67c0f88c00 gtk-demo: add a demo for TextView undo/redo 2019-11-05 10:27:29 -08:00
Christian Hergert
e93408e962 gtk-demo: add an undo demo for GtkEntry 2019-11-05 10:27:29 -08:00
Christian Hergert
6d193d7cb4 gtk-demo: wrap text operations in irreversible actions
This ensures that the actions to set the text for the demo tabs cannot
be undone. This matches the previous behavior for GtkTextBuffer.
2019-11-05 10:27:29 -08:00
Christian Hergert
fb4fbfb2a8 text: add undo support to GtkText
This adds support using the GtkTextHistory helper for undo/redo to the
GtkText widget. It is similar in use to GtkTextView, but with a simplified
interface.

You can disable undo support using the GtkText:enable-undo property. By
default, it is enabled.
2019-11-05 10:27:29 -08:00
Christian Hergert
7e77afe94c entrybuffer: remove text in ::deleted-text default handler
This changes the semantics of ::deleted-text to perform the removal of
text in the default handler. This means, that if you want the old behavior
where your signal handler is called after the text has been deleted, you
should connect with G_CONNECT_AFTER in your signal handler (or use
g_signal_connect_after).

Without this change, there was never a way to get the deleted-text before
the operation had completed and this is necessary to provide undo support
to the text widgets.
2019-11-05 10:27:29 -08:00
Christian Hergert
7587996279 editable: add enable-undo property
This property is intended to be mapped to a GtkText so that undo/redo
support can be used from a number of editable widgets.
2019-11-05 10:27:27 -08:00
Christian Hergert
15b3c0f563 textview: add undo/redo support to GtkTextView
This builds upon the GtkTextHistory helper to provide undo and redo support
for the GtkTextView widget and GtkTextBuffer object.

You can undo/redo using familiar shortcuts such as Primary+Z,
Primary+Shift+Z, ad Primary+Y.

Developers that wish to disable undo, should set the
GtkTextBuffer:enable-undo property to FALSE.

You can wrap irreversible actions
gtk_text_buffer_begin_irreversible_action() and
gtk_text_buffer_end_irreversible_action(). This will cause the undo stack
to drop all undo/redo actions and the changes made between them will be
the "initial state" of the buffer.

Calling gtk_text_buffer_set_text() will do this automatically for you.
2019-11-05 09:34:29 -08:00
Christian Hergert
5e341210a1 texthistory: add GtkTextHistory helper
The GtkTextHistory helper provides the fundamental undo/redo stack that
can be integrated with other text widgets. It allows coalescing related
actions to reduce both the number of undo actions to the user as well as
the memory overhead.

A new istring helper is used by GtkTextHistory to allow for "inline
strings" that gracefully grow to using allocations with g_realloc(). This
ensure that most undo operations require no additional allocations other
than the struct for the action itself.

A queue of undoable and redoable actions are maintained and the link for
the queue is embedded in the undo action union. This allows again, for
reducing the number of allocations involved for undo operations.
2019-11-05 09:34:29 -08:00
Daniel Mustieles
fbea677a5c Updated Spanish translation 2019-11-05 15:44:34 +01:00
Emmanuele Bassi
b271db4f5b ci: Allow msys2 jobs to fail
The msys2 runner has started failing for internal reasons:

 - gtk-3-24 times out
 - master fails with a ld.exe assertion:
   BFD (GNU Binutils) 2.33.1 assertion fail
   ../../binutils-2.33.1/bfd/cofflink.c:2348

Both seem related to some MSYS2 issue. Until the runner is updated, we
should not block on it.
2019-11-05 10:44:05 +00:00
Emmanuele Bassi
b5ed2d310e tests: Add label-sizing.ui to the XFAIL list
Changes in Pango may make this test fail.
2019-11-04 23:46:22 +00:00
Emmanuele Bassi
3bf9277de6 Revert "Adwaita: radios & checkboxes styling updates"
This reverts commit 427b5d187c.

The commit breaks Adwaita:

Theme parsing error: gtk-contained.css:1191:28-44: No property named "-gtk-icon-effect"
2019-11-04 23:35:49 +00:00
Matthias Clasen
53c9eb5a5b Move the ifdef to the right spot 2019-11-04 23:24:49 +00:00
Matthias Clasen
6e5da14294 cell text: Handle new pango enum values
The PangoUnderline enum grew some new values.
2019-11-04 23:14:44 +00:00
Jakub Steiner
427b5d187c Adwaita: radios & checkboxes styling updates
- port from gtk3
2019-11-04 19:41:58 +01:00
Benjamin Otte
5d07877b35 Merge branch 'wip/sadiq/fix-leak' into 'master'
selection-output-stream-x11: Fix a memory leak

See merge request GNOME/gtk!1149
2019-11-04 17:46:28 +00:00
Benjamin Otte
3086715d54 Merge branch 'gtkstack-addnamed-return' into 'master'
stack: return the stack page when adding a child, to ease setting props

See merge request GNOME/gtk!1161
2019-11-04 02:35:22 +00:00
Andy Holmes
44093f4966 stack: return the stack page when adding a child, to ease setting props 2019-11-03 18:05:03 -08:00
Christian Hergert
6d16f7ad35 textview: use g_slice_new0 for proper initial state
This fixes the missuse of the GList embedded node for prev/next.
2019-11-01 11:37:07 -07:00
Matthias Clasen
5f627a2cb6 Merge branch 'reftest-fixes' into 'master'
Reftest fixes

See merge request GNOME/gtk!1157
2019-11-01 17:45:38 +00:00
Matthias Clasen
34d002121d reftests: Print out a helpful error
When module loading fails, print out the error.
2019-11-01 13:37:52 -04:00
Matthias Clasen
22bb1bd568 reftests: Drop libtool hack
We are not using libtool anymore.
2019-11-01 13:37:43 -04:00
Matthias Clasen
28898445ff Merge branch 'bump-pango' into 'master'
Bump pango

See merge request GNOME/gtk!1154
2019-11-01 17:26:33 +00:00
Matthias Clasen
828b58247c label: Handle new pango attributes
overline and overline-color were introduced in Pango 1.45.
2019-11-01 13:01:54 -04:00
Matthias Clasen
de29c3e193 label: Handle insert_hyphens pango attribute
This was introduced in Pango 1.44.4.
2019-11-01 13:01:54 -04:00
Matthias Clasen
8ccf2a722a gsk: Stop using deprecated pango api
Shape engines are not used anymore.
2019-11-01 13:01:54 -04:00
Matthias Clasen
fa8ce17e1e build: We no longer need freetype 2019-11-01 13:01:54 -04:00
Matthias Clasen
4a2f3130d2 gtk-demo: Use harfbuzz for font features
We don't need freetype anymore here; harfbuzz
has what we need.
2019-11-01 13:01:54 -04:00
Matthias Clasen
eaa6301e53 Port the font chooser to just use harfbuzz 2019-11-01 13:01:54 -04:00
Matthias Clasen
41c52e955d Bump the pango dependency
This lets us avoid freetype uses, and simplifies
some other things as well.
2019-11-01 13:01:54 -04:00
Matthias Clasen
eca7fa075e Merge branch 'fix-print-dialog' into 'master'
Update the print dialog for headerbar changes

See merge request GNOME/gtk!1156
2019-11-01 17:00:34 +00:00
Matthias Clasen
19a4e76034 Update the print dialog for headerbar changes
This was breaking the templates test.
2019-11-01 12:51:42 -04:00
Matthias Clasen
6cacff9df1 Merge branch 'ci-update' into 'master'
Update the CI image

See merge request GNOME/gtk!1155
2019-11-01 16:30:17 +00:00
Emmanuele Bassi
2d309725c9 ci: Add internal links to the HTML report
Makes it easier to link to various sections, and to specific failures.
2019-11-01 15:44:12 +00:00
Emmanuele Bassi
a5c00685c5 ci: Add diffutils to the CI image
Some transitive dependency got dropped, and we lost diff.
2019-11-01 15:22:02 +00:00
Emmanuele Bassi
48cc26246f Check for diff's availability
The tests suite calls `diff` in various places, which means we need to
check if it's installed.
2019-11-01 15:20:47 +00:00
Benjamin Otte
4b41dd4eb1 Merge branch 'otte/for-master' into 'master'
Otte/for master

See merge request GNOME/gtk!1153
2019-11-01 14:13:28 +00:00
Benjamin Otte
41beae1956 vulkan: Add missing enum value
Also update comment to point to new header after Vulkan reorganized
their repositories.
2019-11-01 14:52:36 +01:00
Emmanuele Bassi
c48fe6d7ec ci: Update the image to Fedora 31
Fedora 31 ships with a newer version of Pango.
2019-11-01 12:52:19 +00:00
Matthias Clasen
a31a80277c Merge branch 'fallback-rendering' into 'master'
Fallback rendering

See merge request GNOME/gtk!1152
2019-10-31 02:55:34 +00:00
Matthias Clasen
745a701b3d inspector: Add a switch for fallback rendering 2019-10-30 22:31:47 -04:00
Matthias Clasen
d4c97ea2b4 gl: Use the fallback debug flag
This debug flag was unused; use it to enable
fallback highlighting at runtime.
2019-10-30 22:31:47 -04:00
Matthias Clasen
03738634ac inspector: Remove fallback from logs
There are no logs that this debug flag produces.
2019-10-30 22:31:47 -04:00
Matthias Clasen
9dd8652a66 Merge branch 'wl-key-repeat' into 'master'
wayland: Rely on server key repeat info

See merge request GNOME/gtk!1150
2019-10-30 02:39:49 +00:00
Matthias Clasen
cb81a06793 wayland: Drop the keyboard settings object
It is no longer used.
2019-10-29 22:20:57 -04:00
Matthias Clasen
4d9cc483c9 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:58:45 -04:00
Benjamin Otte
4cca27a7af builder: Allow parsing G_TYPE_BYTES from strings
Just create a bytes containing the literal string.
2019-10-29 04:56:19 +01:00
Benjamin Otte
553a9c292d 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-29 04:56:19 +01:00
Benjamin Otte
abd4754648 messagedialog: Remove useless GTK_TYPE_BUILDABLE interface
It was just chaining up.
2019-10-29 04:56:19 +01:00
Mohammed Sadiq
e79d585b00 gdkselectionoutputstream-x11: Fix a memory leak 2019-10-27 14:05:46 +05:30
Matthias Clasen
1f0310ddff gtk-demo: Add a scrolling image demo
This tests big textures.
2019-10-22 21:20:36 -04:00
Matthias Clasen
0284d40e24 window: Unrealize renderer before children
Unrealize the GSK renderer before destroying children.
This makes the renderer drop any texture caches that
it might have, so that we don't needlessly download
them when releasing the widget-side holder objects.

As a fortunate side effect, this fixes crashes on
exit with GtkGLArea-containing windows under Wayland.
2019-10-22 20:28:28 -04:00
Matthias Clasen
ffaf26fdf5 Merge branch 'readonly-all-the-things' into 'master'
Readonly all the things

See merge request GNOME/gtk!1145
2019-10-22 13:23:06 +00:00
Matthias Clasen
5b508ea94a Revert "gl: Speed up icon cache lookups"
This reverts commit dd5ee87b5b.
2019-10-22 07:16:41 -04:00
Matthias Clasen
472d8eebbe gl: Avoid pointless iteration 2019-10-22 07:16:41 -04:00
Matthias Clasen
dd316c8051 gl: Add some comments 2019-10-22 07:16:41 -04:00
Matthias Clasen
1038bc781a Revert "Cache glyph textures in render nodes"
This reverts commit c5af463843.
2019-10-22 07:16:41 -04:00
Timm Bäder
44137574a1 inspector: Fix expander arrow node names
They vanished after the GtkExpander node rename
2019-10-22 09:37:08 +02:00
Timm Bäder
6b07ce2b13 filechooserwidget: Remove unused function parameter 2019-10-22 09:37:08 +02:00
Timm Bäder
008e8076a1 filechooserwidget: Inline function into only caller 2019-10-22 09:37:08 +02:00
Timm Bäder
2cd4b255cd placesview: open address popover upwards 2019-10-22 09:37:08 +02:00
Timm Bäder
11a38dd455 entry: Remove unused function 2019-10-22 09:37:08 +02:00
Timm Bäder
dfcc40ef9a text: Propagate pango attributes to placeholder
Not sure if this is really always wanted or whether we need to filter
the attributes, or even create a separate property for them.
2019-10-22 09:37:08 +02:00
Timm Bäder
1882034323 text: Fix _set_attributes docs
The list is nullable.
2019-10-22 09:37:08 +02:00
Timm Bäder
aaaa3e141b placessidebar: Remove some unused members 2019-10-22 09:37:08 +02:00
Timm Bäder
15af87345d placesview: Use proper setters for properties 2019-10-22 09:37:08 +02:00
Timm Bäder
640db05b18 text: Remove some unused members 2019-10-22 09:37:08 +02:00
Timm Bäder
31ae93475d text: Fix context menu position
Fixes #2209
2019-10-22 09:37:08 +02:00
Timm Bäder
8fc4d229da text: Inline function into only caller 2019-10-22 09:37:08 +02:00
Timm Bäder
a62efb8257 text: Remove gtk_text_get_text_allocation
We can just replace that with get_width/get_height everywhere.
2019-10-22 09:37:08 +02:00
Timm Bäder
acf927fe14 text: Don't destroy pango layout in size_allocate
It's not needed.
2019-10-22 09:37:08 +02:00
Timm Bäder
ca71340c6b Adwaita: Fix menubutton in headerbar margins
Add the margins to the menubutton and not the button inside the
menubutton. This way popovers properly point to the inner button again
instead to somewhere 6px off.
2019-10-22 09:37:08 +02:00
Timm Bäder
350495cf1c Adwaita: Remove padding from popover.menu
The padding belongs to the contents subnode in this case.
2019-10-22 09:37:08 +02:00
Timm Bäder
426d5ca1b7 filechooserwidget: Add .menu to right-click popover
Make it look like the other menus.
2019-10-22 09:37:08 +02:00
Timm Bäder
aaae141687 filechooserwidget: Focus the searchbar when searching
This code path is taken if the search is already active, so focus the
search entry.
2019-10-22 09:37:08 +02:00
Timm Bäder
4826255ea3 filechooserwidget: Rename a callback 2019-10-22 09:37:08 +02:00
Timm Bäder
9ba08a09cb shortcutlabel: Inherit from GtkWidget 2019-10-22 09:37:08 +02:00
Timm Bäder
bb2c68452c shortcutlabel: Inherit from GtkWidget 2019-10-22 09:37:07 +02:00
Timm Bäder
23be10cf69 searchentry: Make the text entry expand
Fixes the broken layout.
2019-10-22 09:37:07 +02:00
Timm Bäder
17a111968b text: Remove an unnecessary queue_draw() call 2019-10-22 09:37:07 +02:00
Matthias Clasen
d3431f569c Revert "inspector: Fix node recording"
This reverts commit ba7649b388.
2019-10-22 01:32:51 -04:00
Matthias Clasen
7a73f43de3 Merge branch 'wip/matthiasc/icon-theme' into 'master'
Misc icon theme cleanups

See merge request GNOME/gtk!1139
2019-10-19 22:43:34 +00: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
Matthias Clasen
1dd55ed600 Drop gtk_icon_info_new_for_pixbuf
It is better to keep icon infos as something you
only get from the icon theme.
2019-10-18 08:53:23 -05:00
Matthias Clasen
416b2cd18d Move symbolic pixbuf recoloring code
This function is better off next to the other
symbolic png code in gdkpixbufutils.c.
2019-10-18 08:53:23 -05:00
Matthias Clasen
15dffb47dc icon theme: Drop icon_file from GtkIconInfo
It is not used anymore.
2019-10-18 08:53:23 -05:00
Matthias Clasen
20e70a78c4 Drop another use of icon_file
Stop using icon_file when loading symbolic svgs.
2019-10-18 08:53:23 -05:00
Matthias Clasen
e190b4536a Drop another use of icon_file 2019-10-18 08:53:23 -05:00
Matthias Clasen
3c219bf968 Add another symbolic pixbuf helper 2019-10-18 08:53:23 -05:00
Matthias Clasen
c3de5e3624 Avoid a use of icon_file
This is a step towards getting rid of GtkIconInfo->icon_file.
2019-10-18 08:53:23 -05:00
Matthias Clasen
dd69bcabf7 icon theme: Start to untangle GtkIconInfo
GtkIconInfo contains too much redundant data,
and it is hard to know which fields are to be
used when.

This commit starts to move towards dropping the
icon_file field - we prefer to work with the
filename directly, since it lets us avoid mime
sniffing and strdups.
2019-10-18 08:53:23 -05:00
Matthias Clasen
6373ced608 Drop gtk_icon_theme_get_example_icon_name
This function is not useful. Every icon theme
on my system either does not have that field,
or has it as 'folder'. So, just use 'folder'
when you need an example icon.
2019-10-18 08:53:23 -05:00
Matthias Clasen
2ea95a7674 Drop gtk_icon_theme_list_contexts
Contexts in icon themes are not useful for anything.
2019-10-18 08:53:23 -05:00
Matthias Clasen
dbbb7eef15 testicontheme: Remove useless function
Contexts in icon themes are not useful for anything,
so drop this function from testicontheme.
2019-10-18 08:53:23 -05:00
Matthias Clasen
233d096261 icon theme: Avoid a string copy
This is in an error path, so mostly cosmetic.
2019-10-18 08:53:23 -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
828 changed files with 168773 additions and 50577 deletions

View File

@@ -12,8 +12,8 @@ stages:
- subprojects/libepoxy/
- subprojects/pango/
fedora-x86_64:
image: registry.gitlab.gnome.org/gnome/gtk/master:v6
fedora-x86_64: &fedora-x86_64-defaults
image: registry.gitlab.gnome.org/gnome/gtk/master:v7
stage: build
script:
- bash -x ./.gitlab-ci/test-docker.sh
@@ -33,6 +33,11 @@ fedora-x86_64:
key: "$CI_JOB_NAME"
<<: *cache-paths
fedora-x86_64-staticlibs:
variables:
EXTRA_MESON_FLAGS: "-Ddefault_library=both"
<<: *fedora-x86_64-defaults
.mingw-defaults: &mingw-defaults
stage: build
tags:
@@ -40,6 +45,7 @@ fedora-x86_64:
script:
- C:\msys64\usr\bin\pacman --noconfirm -Syyuu
- C:\msys64\usr\bin\bash -lc "bash -x ./.gitlab-ci/test-msys2.sh"
allow_failure: true
cache:
key: "%CI_JOB_NAME%"
<<: *cache-paths

View File

@@ -1,7 +1,6 @@
FROM fedora:30
FROM fedora:31
RUN dnf -y install \
hicolor-icon-theme \
adwaita-icon-theme \
atk-devel \
at-spi2-atk-devel \
@@ -14,6 +13,7 @@ RUN dnf -y install \
dbus-daemon \
dejavu-sans-mono-fonts \
desktop-file-utils \
diffutils \
elfutils-libelf-devel \
fribidi-devel \
gcc \
@@ -32,6 +32,7 @@ RUN dnf -y install \
gstreamer1-plugins-bad-free-devel \
gstreamer1-plugins-base-devel \
gtk-doc \
hicolor-icon-theme \
iso-codes \
itstool \
json-glib-devel \

View File

@@ -149,11 +149,11 @@ ul.images li {
<article>
<section>
<div class="summary">
<h3>Summary</h3>
<h3><a name="summary">Summary</a></h3>
<ul>
<li><strong>Total units:</strong> {{ report.total_units }}</li>
<li><strong>Passed:</strong> {{ report.total_successes }}</li>
<li><strong>Failed:</strong> {{ report.total_failures }}</li>
<li><strong>Passed:</strong> <a href="#passed">{{ report.total_successes }}</a></li>
<li><strong>Failed:</strong> <a href="#failures">{{ report.total_failures }}</a></li>
</ul>
</div>
</section>
@@ -161,7 +161,7 @@ ul.images li {
{% for suite_result in report.results_list %}
<section>
<div class="result">
<h3>Suite: {{ suite_result.suite_name }}</h3>
<h3><a name="results">Suite: {{ suite_result.suite_name }}</a></h3>
<ul>
<li><strong>Units:</strong> {{ suite_result.n_units }}</li>
<li><strong>Passed:</strong> {{ suite_result.n_successes }}</li>
@@ -169,7 +169,7 @@ ul.images li {
</ul>
<div class="successes">
<h4>Passed</h4>
<h4><a name="passed">Passed</a></h4>
<ul class="passed">
{% for success in suite_result.successes if success.result == 'OK' %}
<li>{{ success.name }} - result: <span class="result pass">{{ success.result }}</li>
@@ -178,7 +178,7 @@ ul.images li {
{% endfor %}
</ul>
<h4>Skipped</h4>
<h4><a name="skipped">Skipped</a></h4>
<ul>
{% for success in suite_result.successes if success.result == 'SKIP' %}
<li>{{ success.name }} - result: <span class="result skip">{{ success.result }}</li>
@@ -187,10 +187,10 @@ ul.images li {
{% endfor %}
</ul>
<h4>Expected failures</h4>
<h4><a name="expected-fail">Expected failures</a></h4>
<ul>
{% for success in suite_result.successes if success.result == 'EXPECTEDFAIL' %}
<li>{{ success.name }} - result: <span class="result xfail">{{ success.result }}</span><br/>
<li><a name="{{ success.name }}">{{ success.name }}</a> - result: <span class="result xfail">{{ success.result }}</span><br/>
{% if success.stdout %}
Output: <pre>{{ success.stdout }}</pre>
{% endif %}
@@ -209,10 +209,10 @@ ul.images li {
</div>
<div class="failures">
<h4>Failed</h4>
<h4><a name="failed">Failed</a></h4>
<ul class="failed">
{% for failure in suite_result.failures if failure.result == 'FAIL' %}
<li>{{ failure.name }} - result: <span class="result fail">{{ failure.result }}</span><br/>
<li><a name="{{ failure.name }}">{{ failure.name }}</a> - result: <span class="result fail">{{ failure.result }}</span><br/>
{% if failure.stdout %}
Output: <pre>{{ failure.stdout }}</pre>
{% endif %}
@@ -229,10 +229,10 @@ ul.images li {
{% endfor %}
</ul>
<h4>Timed out</h4>
<h4><a name="timed-out">Timed out</a></h4>
<ul class="failed">
{% for failure in suite_result.failures if failure.result == 'TIMEOUT' %}
<li>{{ failure.name }} - result: <span class="result fail">{{ failure.result }}</span><br/>
<li><a name="{{ failure.name }}">{{ failure.name }}</a> - result: <span class="result fail">{{ failure.result }}</span><br/>
{% if failure.stdout %}
Output: <pre>{{ failure.stdout }}</pre>
{% endif %}

View File

@@ -2,7 +2,7 @@
set -e
TAG="registry.gitlab.gnome.org/gnome/gtk/master:v6"
TAG="registry.gitlab.gnome.org/gnome/gtk/master:v7"
sudo docker build --build-arg HOST_USER_ID="$UID" --tag "${TAG}" \
--file "Dockerfile" .

View File

@@ -17,6 +17,7 @@ meson \
-Dbroadway-backend=true \
-Dvulkan=yes \
--werror \
${EXTRA_MESON_FLAGS:-} \
_build $srcdir
unset CCACHE_DISABLE

View File

@@ -169,6 +169,7 @@ constraint_view_init (ConstraintView *self)
GListModel *guides;
GListModel *children;
GListModel *constraints;
GtkFilter *filter;
manager = gtk_constraint_layout_new ();
gtk_widget_set_layout_manager (GTK_WIDGET (self), manager);
@@ -176,8 +177,12 @@ constraint_view_init (ConstraintView *self)
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);
filter = gtk_custom_filter_new (omit_internal, NULL, NULL);
constraints = (GListModel *)gtk_filter_list_model_new (all_constraints, filter);
g_object_unref (filter);
filter = gtk_custom_filter_new (omit_internal, NULL, NULL);
children = (GListModel *)gtk_filter_list_model_new (all_children, filter);
g_object_unref (filter);
list = g_list_store_new (G_TYPE_LIST_MODEL);
g_list_store_append (list, children);

View File

@@ -184,58 +184,6 @@ max_input (GtkSpinButton *spin_button,
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)
{
@@ -244,16 +192,12 @@ guide_editor_constructed (GObject *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)
{

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

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

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

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

View File

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

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

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

View File

@@ -0,0 +1,49 @@
/* Awards
*
* This demo demonstrates how to use lists to show the awards you have collected
* while exploring this demo.
*
*/
#include <gtk/gtk.h>
/* Include the header for accessing the awards */
#include "award.h"
static GtkWidget *window = NULL;
GtkWidget *
do_awardview (GtkWidget *do_widget)
{
if (!window)
{
GtkWidget *sw, *listview;
GListModel *list;
window = gtk_window_new (GTK_WINDOW_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);
listview = gtk_list_view_new_with_factory (
gtk_builder_list_item_factory_new_from_resource (NULL, "/awardview/awardlistitem.ui"));
list = gtk_award_get_list ();
gtk_list_view_set_model (GTK_LIST_VIEW (listview), list);
g_object_unref (list);
gtk_list_view_set_show_separators (GTK_LIST_VIEW (listview), TRUE);
gtk_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

@@ -59,7 +59,6 @@ do_builder (GtkWidget *do_widget)
builder = gtk_builder_new_from_resource ("/builder/demo.ui");
gtk_builder_connect_signals (builder, NULL);
window = GTK_WIDGET (gtk_builder_get_object (builder, "window1"));
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));

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));

File diff suppressed because it is too large Load Diff

View File

@@ -24,7 +24,6 @@ do_cursors (GtkWidget *do_widget)
GtkBuilder *builder;
builder = gtk_builder_new_from_resource ("/cursors/cursors.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));

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,29 @@
<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_settings">
<file>listview_settings.ui</file>
</gresource>
<gresource prefix="/listview_weather">
<file compressed="true">listview_weather.txt</file>
</gresource>
<gresource prefix="/listview_colors">
<file compressed="true">color.names.txt</file>
</gresource>
<gresource prefix="/shortcuts">
<file>shortcuts.ui</file>
<file>shortcuts-builder.ui</file>
@@ -144,6 +170,7 @@
</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>
@@ -164,8 +191,8 @@
<file>drawingarea.c</file>
<file>dnd.c</file>
<file>editable_cells.c</file>
<file>entry_buffer.c</file>
<file>entry_completion.c</file>
<file>entry_undo.c</file>
<file>expander.c</file>
<file>filtermodel.c</file>
<file>fishbowl.c</file>
@@ -179,12 +206,20 @@
<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_applauncher.c</file>
<file>listview_colors.c</file>
<file>listview_clocks.c</file>
<file>listview_filebrowser.c</file>
<file>listview_minesweeper.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>
@@ -216,6 +251,7 @@
<file>spinner.c</file>
<file>tabs.c</file>
<file>tagged_entry.c</file>
<file>textundo.c</file>
<file>textview.c</file>
<file>textscroll.c</file>
<file>theming_style_classes.c</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

@@ -1,28 +1,29 @@
/* Entry/Entry Buffer
/* Entry/Entry Undo
*
* GtkEntryBuffer provides the text content in a GtkEntry.
* Applications can provide their own buffer implementation,
* e.g. to provide secure handling for passwords in memory.
* GtkEntry can provide basic Undo/Redo support using standard keyboard
* accelerators such as Primary+z to undo and Primary+Shift+z to redo.
* Additionally, Primary+y can be used to redo.
*
* Use gtk_entry_set_enable_undo() to enable undo/redo support.
*/
#include <glib/gi18n.h>
#include <gtk/gtk.h>
GtkWidget *
do_entry_buffer (GtkWidget *do_widget)
do_entry_undo (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
GtkWidget *vbox;
GtkWidget *label;
GtkWidget *entry;
GtkEntryBuffer *buffer;
if (!window)
{
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), "Entry Buffer");
gtk_window_set_title (GTK_WINDOW (window), "Entry Undo");
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed), &window);
@@ -33,22 +34,13 @@ do_entry_buffer (GtkWidget *do_widget)
label = gtk_label_new (NULL);
gtk_label_set_markup (GTK_LABEL (label),
"Entries share a buffer. Typing in one is reflected in the other.");
"Use Primary+z or Primary+Shift+z to undo or redo changes");
gtk_container_add (GTK_CONTAINER (vbox), label);
/* Create a buffer */
buffer = gtk_entry_buffer_new (NULL, 0);
/* Create our first entry */
entry = gtk_entry_new_with_buffer (buffer);
/* Create our entry */
entry = gtk_entry_new ();
gtk_editable_set_enable_undo (GTK_EDITABLE (entry), TRUE);
gtk_container_add (GTK_CONTAINER (vbox), entry);
/* Create the second entry */
entry = gtk_entry_new_with_buffer (buffer);
gtk_entry_set_visibility (GTK_ENTRY (entry), FALSE);
gtk_container_add (GTK_CONTAINER (vbox), entry);
g_object_unref (buffer);
}
if (!gtk_widget_get_visible (window))

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

@@ -122,7 +122,6 @@ do_filtermodel (GtkWidget *do_widget)
GtkBuilder *builder;
builder = gtk_builder_new_from_resource ("/filtermodel/filtermodel.ui");
gtk_builder_connect_signals (builder, NULL);
window = GTK_WIDGET (gtk_builder_get_object (builder, "window1"));
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));

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;
@@ -226,8 +226,8 @@ set_widget_type (GtkFishbowl *fishbowl,
}
void
next_button_clicked_cb (GtkButton *source,
gpointer user_data)
fishbowl_next_button_clicked_cb (GtkButton *source,
gpointer user_data)
{
GtkFishbowl *fishbowl = user_data;
int new_index;
@@ -241,8 +241,8 @@ next_button_clicked_cb (GtkButton *source,
}
void
prev_button_clicked_cb (GtkButton *source,
gpointer user_data)
fishbowl_prev_button_clicked_cb (GtkButton *source,
gpointer user_data)
{
GtkFishbowl *fishbowl = user_data;
int new_index;
@@ -256,8 +256,8 @@ prev_button_clicked_cb (GtkButton *source,
}
void
changes_toggled_cb (GtkToggleButton *button,
gpointer user_data)
fishbowl_changes_toggled_cb (GtkToggleButton *button,
gpointer user_data)
{
if (gtk_toggle_button_get_active (button))
gtk_button_set_icon_name (GTK_BUTTON (button), "changes-prevent");
@@ -265,6 +265,14 @@ changes_toggled_cb (GtkToggleButton *button,
gtk_button_set_icon_name (GTK_BUTTON (button), "changes-allow");
}
char *
format_header_cb (GObject *object,
guint count,
double fps)
{
return g_strdup_printf ("%u Icons, %.2f fps", count, fps);
}
GtkWidget *
do_fishbowl (GtkWidget *do_widget)
{
@@ -288,12 +296,6 @@ do_fishbowl (GtkWidget *do_widget)
g_type_ensure (GTK_TYPE_FISHBOWL);
builder = gtk_builder_new_from_resource ("/fishbowl/fishbowl.ui");
gtk_builder_add_callback_symbols (builder,
"next_button_clicked_cb", G_CALLBACK (next_button_clicked_cb),
"prev_button_clicked_cb", G_CALLBACK (prev_button_clicked_cb),
"changes_toggled_cb", G_CALLBACK (changes_toggled_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);

View File

@@ -15,42 +15,32 @@
<child>
<object class="GtkButton">
<property name="icon-name">pan-start-symbolic</property>
<signal name="clicked" handler="prev_button_clicked_cb" object="bowl" swapped="no"/>
<signal name="clicked" handler="fishbowl_prev_button_clicked_cb" object="bowl" swapped="no"/>
</object>
</child>
<child>
<object class="GtkButton">
<property name="icon-name">pan-end-symbolic</property>
<signal name="clicked" handler="next_button_clicked_cb" object="bowl" swapped="no"/>
<signal name="clicked" handler="fishbowl_next_button_clicked_cb" object="bowl" swapped="no"/>
</object>
</child>
</object>
</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">
<closure type="gchararray" function="format_header_cb">
<lookup name="count">bowl</lookup>
<lookup name="framerate">bowl</lookup>
</closure>
</binding>
</object>
</child>
<child type="end">
<object class="GtkToggleButton" id="changes_allow">
<property name="icon-name">changes-allow</property>
<property name="relief">none</property>
<signal name="notify::active" handler="changes_toggled_cb"/>
<signal name="notify::active" handler="fishbowl_changes_toggled_cb"/>
</object>
</child>
</object>

View File

@@ -4,6 +4,8 @@
* as needed and support sorting and filtering.
*
* The children of a GtkFlowBox are regular widgets
*
* The dataset used here has 665 colors.
*/
#include <gtk/gtk.h>

View File

@@ -13,7 +13,7 @@
<property name="can-focus">1</property>
<property name="receives-default">1</property>
<property name="tooltip-text">Reset</property>
<signal name="clicked" handler="reset" swapped="no"/>
<signal name="clicked" handler="font_features_reset_features" swapped="no"/>
<child>
<object class="GtkImage">
<property name="icon-name">view-refresh-symbolic</property>
@@ -42,7 +42,7 @@
<property name="receives-default">1</property>
<property name="font">Sans 12</property>
<property name="level">family|style|size|variations|features</property>
<signal name="font-set" handler="font_changed" swapped="no"/>
<signal name="font-set" handler="font_features_font_changed" swapped="no"/>
</object>
</child>
<child>
@@ -63,7 +63,7 @@
<object class="GtkComboBox" id="script_lang">
<property name="can-focus">1</property>
<property name="margin-top">10</property>
<signal name="changed" handler="script_changed" swapped="no"/>
<signal name="changed" handler="font_features_script_changed" swapped="no"/>
<child>
<object class="GtkCellRendererText"/>
<attributes>
@@ -137,7 +137,7 @@
Разъяренный чтец эгоистично бьёт пятью жердями шустрого фехтовальщика. Наш банк вчера же выплатил Ф.Я. Эйхгольду комиссию за ценные вещи. Эх, чужак, общий съём цен шляп (юфть) вдрызг! В чащах юга жил бы цитрус? Да, но фальшивый экземпляр!
Τάχιστη αλώπηξ βαφής ψημένη γη, δρασκελίζει υπέρ νωθρού κυνός</property>
<signal name="activate" handler="stop_edit"/>
<signal name="activate" handler="font_features_stop_edit"/>
<property name="valign">start</property>
<property name="width-chars">50</property>
</object>
@@ -181,7 +181,7 @@
<property name="icon-name">document-edit-symbolic</property>
<property name="halign">end</property>
<property name="valign">end</property>
<signal name="toggled" handler="toggle_edit"/>
<signal name="toggled" handler="font_features_toggle_edit"/>
</object>
</child>
</object>

View File

@@ -15,10 +15,6 @@
#include <pango/pangofc-font.h>
#include <hb.h>
#include <hb-ot.h>
#include <hb-ft.h>
#include <freetype/ftmm.h>
#include <freetype/ftsnames.h>
#include <freetype/ttnameid.h>
#include <glib/gi18n.h>
#include "open-type-layout.h"
@@ -484,7 +480,6 @@ update_script_combo (void)
GtkListStore *store;
hb_font_t *hb_font;
gint i, j, k;
FT_Face ft_face;
PangoFont *pango_font;
GHashTable *tags;
GHashTableIter iter;
@@ -505,8 +500,7 @@ update_script_combo (void)
store = gtk_list_store_new (4, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT);
pango_font = get_pango_font ();
ft_face = pango_fc_font_lock_face (PANGO_FC_FONT (pango_font)),
hb_font = hb_ft_font_create (ft_face, NULL);
hb_font = pango_font_get_hb_font (pango_font);
tags = g_hash_table_new_full (tag_pair_hash, tag_pair_equal, g_free, NULL);
@@ -545,11 +539,8 @@ update_script_combo (void)
}
}
}
hb_face_destroy (hb_face);
}
pango_fc_font_unlock_face (PANGO_FC_FONT (pango_font));
g_object_unref (pango_font);
g_hash_table_iter_init (&iter, tags);
@@ -607,7 +598,6 @@ update_features (void)
GtkTreeIter iter;
guint script_index, lang_index;
PangoFont *pango_font;
FT_Face ft_face;
hb_font_t *hb_font;
GList *l;
@@ -632,8 +622,7 @@ update_features (void)
-1);
pango_font = get_pango_font ();
ft_face = pango_fc_font_lock_face (PANGO_FC_FONT (pango_font)),
hb_font = hb_ft_font_create (ft_face, NULL);
hb_font = pango_font_get_hb_font (pango_font);
if (hb_font)
{
@@ -715,11 +704,8 @@ update_features (void)
g_free (feat);
}
hb_face_destroy (hb_face);
}
pango_fc_font_unlock_face (PANGO_FC_FONT (pango_font));
g_object_unref (pango_font);
}
@@ -800,24 +786,29 @@ axes_equal (gconstpointer v1, gconstpointer v2)
}
static void
add_axis (FT_Var_Axis *ax, FT_Fixed value, int i)
add_axis (hb_face_t *hb_face,
hb_ot_var_axis_info_t *ax,
float value,
int i)
{
GtkWidget *axis_label;
GtkWidget *axis_entry;
GtkWidget *axis_scale;
GtkAdjustment *adjustment;
Axis *axis;
char name[20];
unsigned int name_len = 20;
axis_label = gtk_label_new (ax->name);
hb_ot_name_get_utf8 (hb_face, ax->name_id, HB_LANGUAGE_INVALID, &name_len, name);
axis_label = gtk_label_new (name);
gtk_widget_set_halign (axis_label, GTK_ALIGN_START);
gtk_widget_set_valign (axis_label, GTK_ALIGN_BASELINE);
gtk_grid_attach (GTK_GRID (variations_grid), axis_label, 0, i, 1, 1);
adjustment = gtk_adjustment_new ((double)FixedToFloat(value),
(double)FixedToFloat(ax->minimum),
(double)FixedToFloat(ax->maximum),
adjustment = gtk_adjustment_new (value, ax->min_value, ax->max_value,
1.0, 10.0, 0.0);
axis_scale = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, adjustment);
gtk_scale_add_mark (GTK_SCALE (axis_scale), (double)FixedToFloat(ax->def), GTK_POS_TOP, NULL);
gtk_scale_add_mark (GTK_SCALE (axis_scale), ax->default_value, GTK_POS_TOP, NULL);
gtk_widget_set_valign (axis_scale, GTK_ALIGN_BASELINE);
gtk_widget_set_hexpand (axis_scale, TRUE);
gtk_widget_set_size_request (axis_scale, 100, -1);
@@ -842,9 +833,7 @@ add_axis (FT_Var_Axis *ax, FT_Fixed value, int i)
typedef struct {
char *name;
int n_axes;
guint32 *axes;
float *coords;
unsigned int index;
} Instance;
static guint
@@ -870,559 +859,32 @@ free_instance (gpointer data)
Instance *instance = data;
g_free (instance->name);
g_free (instance->axes);
g_free (instance->coords);
g_free (instance);
}
static GHashTable *instances;
typedef struct {
const FT_UShort platform_id;
const FT_UShort encoding_id;
const char fromcode[12];
} FtEncoding;
#define TT_ENCODING_DONT_CARE 0xffff
static const FtEncoding ftEncoding[] = {
{ TT_PLATFORM_APPLE_UNICODE, TT_ENCODING_DONT_CARE, "UTF-16BE" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_ID_ROMAN, "MACINTOSH" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_ID_JAPANESE, "SJIS" },
{ TT_PLATFORM_MICROSOFT, TT_MS_ID_SYMBOL_CS, "UTF-16BE" },
{ TT_PLATFORM_MICROSOFT, TT_MS_ID_UNICODE_CS, "UTF-16BE" },
{ TT_PLATFORM_MICROSOFT, TT_MS_ID_SJIS, "SJIS-WIN" },
{ TT_PLATFORM_MICROSOFT, TT_MS_ID_GB2312, "GB2312" },
{ TT_PLATFORM_MICROSOFT, TT_MS_ID_BIG_5, "BIG-5" },
{ TT_PLATFORM_MICROSOFT, TT_MS_ID_WANSUNG, "Wansung" },
{ TT_PLATFORM_MICROSOFT, TT_MS_ID_JOHAB, "Johab" },
{ TT_PLATFORM_MICROSOFT, TT_MS_ID_UCS_4, "UTF-16BE" },
{ TT_PLATFORM_ISO, TT_ISO_ID_7BIT_ASCII, "ASCII" },
{ TT_PLATFORM_ISO, TT_ISO_ID_10646, "UTF-16BE" },
{ TT_PLATFORM_ISO, TT_ISO_ID_8859_1, "ISO-8859-1" },
};
typedef struct {
const FT_UShort platform_id;
const FT_UShort language_id;
const char lang[8];
} FtLanguage;
#define TT_LANGUAGE_DONT_CARE 0xffff
static const FtLanguage ftLanguage[] = {
{ TT_PLATFORM_APPLE_UNICODE, TT_LANGUAGE_DONT_CARE, "" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_ENGLISH, "en" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_FRENCH, "fr" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_GERMAN, "de" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_ITALIAN, "it" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_DUTCH, "nl" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_SWEDISH, "sv" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_SPANISH, "es" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_DANISH, "da" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_PORTUGUESE, "pt" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_NORWEGIAN, "no" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_HEBREW, "he" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_JAPANESE, "ja" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_ARABIC, "ar" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_FINNISH, "fi" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_GREEK, "el" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_ICELANDIC, "is" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_MALTESE, "mt" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_TURKISH, "tr" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_CROATIAN, "hr" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_CHINESE_TRADITIONAL, "zh-tw" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_URDU, "ur" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_HINDI, "hi" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_THAI, "th" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_KOREAN, "ko" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_LITHUANIAN, "lt" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_POLISH, "pl" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_HUNGARIAN, "hu" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_ESTONIAN, "et" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_LETTISH, "lv" },
/* { TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_SAAMISK, ??? */
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_FAEROESE, "fo" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_FARSI, "fa" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_RUSSIAN, "ru" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_CHINESE_SIMPLIFIED, "zh-cn" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_FLEMISH, "nl" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_IRISH, "ga" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_ALBANIAN, "sq" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_ROMANIAN, "ro" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_CZECH, "cs" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_SLOVAK, "sk" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_SLOVENIAN, "sl" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_YIDDISH, "yi" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_SERBIAN, "sr" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_MACEDONIAN, "mk" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_BULGARIAN, "bg" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_UKRAINIAN, "uk" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_BYELORUSSIAN, "be" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_UZBEK, "uz" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_KAZAKH, "kk" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_AZERBAIJANI, "az" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_AZERBAIJANI_CYRILLIC_SCRIPT, "az" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_AZERBAIJANI_ARABIC_SCRIPT, "ar" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_ARMENIAN, "hy" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_GEORGIAN, "ka" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_MOLDAVIAN, "mo" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_KIRGHIZ, "ky" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_TAJIKI, "tg" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_TURKMEN, "tk" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_MONGOLIAN, "mo" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_MONGOLIAN_MONGOLIAN_SCRIPT,"mo" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_MONGOLIAN_CYRILLIC_SCRIPT, "mo" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_PASHTO, "ps" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_KURDISH, "ku" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_KASHMIRI, "ks" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_SINDHI, "sd" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_TIBETAN, "bo" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_NEPALI, "ne" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_SANSKRIT, "sa" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_MARATHI, "mr" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_BENGALI, "bn" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_ASSAMESE, "as" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_GUJARATI, "gu" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_PUNJABI, "pa" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_ORIYA, "or" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_MALAYALAM, "ml" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_KANNADA, "kn" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_TAMIL, "ta" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_TELUGU, "te" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_SINHALESE, "si" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_BURMESE, "my" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_KHMER, "km" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_LAO, "lo" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_VIETNAMESE, "vi" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_INDONESIAN, "id" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_TAGALOG, "tl" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_MALAY_ROMAN_SCRIPT, "ms" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_MALAY_ARABIC_SCRIPT, "ms" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_AMHARIC, "am" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_TIGRINYA, "ti" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_GALLA, "om" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_SOMALI, "so" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_SWAHILI, "sw" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_RUANDA, "rw" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_RUNDI, "rn" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_CHEWA, "ny" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_MALAGASY, "mg" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_ESPERANTO, "eo" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_WELSH, "cy" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_BASQUE, "eu" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_CATALAN, "ca" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_LATIN, "la" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_QUECHUA, "qu" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_GUARANI, "gn" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_AYMARA, "ay" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_TATAR, "tt" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_UIGHUR, "ug" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_DZONGKHA, "dz" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_JAVANESE, "jw" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_SUNDANESE, "su" },
#if 0 /* these seem to be errors that have been dropped */
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_SCOTTISH_GAELIC },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_IRISH_GAELIC },
#endif
/* The following codes are new as of 2000-03-10 */
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_GALICIAN, "gl" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_AFRIKAANS, "af" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_BRETON, "br" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_INUKTITUT, "iu" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_SCOTTISH_GAELIC, "gd" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_MANX_GAELIC, "gv" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_IRISH_GAELIC, "ga" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_TONGAN, "to" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_GREEK_POLYTONIC, "el" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_GREELANDIC, "ik" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_AZERBAIJANI_ROMAN_SCRIPT,"az" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ARABIC_SAUDI_ARABIA, "ar" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ARABIC_IRAQ, "ar" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ARABIC_EGYPT, "ar" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ARABIC_LIBYA, "ar" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ARABIC_ALGERIA, "ar" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ARABIC_MOROCCO, "ar" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ARABIC_TUNISIA, "ar" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ARABIC_OMAN, "ar" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ARABIC_YEMEN, "ar" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ARABIC_SYRIA, "ar" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ARABIC_JORDAN, "ar" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ARABIC_LEBANON, "ar" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ARABIC_KUWAIT, "ar" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ARABIC_UAE, "ar" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ARABIC_BAHRAIN, "ar" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ARABIC_QATAR, "ar" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_BULGARIAN_BULGARIA, "bg" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_CATALAN_SPAIN, "ca" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_CHINESE_TAIWAN, "zh-tw" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_CHINESE_PRC, "zh-cn" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_CHINESE_HONG_KONG, "zh-hk" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_CHINESE_SINGAPORE, "zh-sg" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_CHINESE_MACAU, "zh-mo" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_CZECH_CZECH_REPUBLIC, "cs" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_DANISH_DENMARK, "da" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_GERMAN_GERMANY, "de" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_GERMAN_SWITZERLAND, "de" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_GERMAN_AUSTRIA, "de" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_GERMAN_LUXEMBOURG, "de" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_GERMAN_LIECHTENSTEI, "de" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_GREEK_GREECE, "el" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ENGLISH_UNITED_STATES, "en" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ENGLISH_UNITED_KINGDOM, "en" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ENGLISH_AUSTRALIA, "en" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ENGLISH_CANADA, "en" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ENGLISH_NEW_ZEALAND, "en" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ENGLISH_IRELAND, "en" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ENGLISH_SOUTH_AFRICA, "en" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ENGLISH_JAMAICA, "en" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ENGLISH_CARIBBEAN, "en" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ENGLISH_BELIZE, "en" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ENGLISH_TRINIDAD, "en" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ENGLISH_ZIMBABWE, "en" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ENGLISH_PHILIPPINES, "en" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SPANISH_SPAIN_TRADITIONAL_SORT,"es" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SPANISH_MEXICO, "es" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SPANISH_SPAIN_INTERNATIONAL_SORT,"es" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SPANISH_GUATEMALA, "es" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SPANISH_COSTA_RICA, "es" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SPANISH_PANAMA, "es" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SPANISH_DOMINICAN_REPUBLIC,"es" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SPANISH_VENEZUELA, "es" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SPANISH_COLOMBIA, "es" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SPANISH_PERU, "es" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SPANISH_ARGENTINA, "es" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SPANISH_ECUADOR, "es" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SPANISH_CHILE, "es" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SPANISH_URUGUAY, "es" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SPANISH_PARAGUAY, "es" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SPANISH_BOLIVIA, "es" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SPANISH_EL_SALVADOR, "es" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SPANISH_HONDURAS, "es" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SPANISH_NICARAGUA, "es" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SPANISH_PUERTO_RICO, "es" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_FINNISH_FINLAND, "fi" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_FRENCH_FRANCE, "fr" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_FRENCH_BELGIUM, "fr" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_FRENCH_CANADA, "fr" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_FRENCH_SWITZERLAND, "fr" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_FRENCH_LUXEMBOURG, "fr" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_FRENCH_MONACO, "fr" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_HEBREW_ISRAEL, "he" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_HUNGARIAN_HUNGARY, "hu" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ICELANDIC_ICELAND, "is" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ITALIAN_ITALY, "it" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ITALIAN_SWITZERLAND, "it" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_JAPANESE_JAPAN, "ja" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_KOREAN_EXTENDED_WANSUNG_KOREA,"ko" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_KOREAN_JOHAB_KOREA, "ko" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_DUTCH_NETHERLANDS, "nl" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_DUTCH_BELGIUM, "nl" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_NORWEGIAN_NORWAY_BOKMAL, "no" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_NORWEGIAN_NORWAY_NYNORSK, "nn" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_POLISH_POLAND, "pl" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_PORTUGUESE_BRAZIL, "pt" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_PORTUGUESE_PORTUGAL, "pt" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_RHAETO_ROMANIC_SWITZERLAND,"rm" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ROMANIAN_ROMANIA, "ro" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_MOLDAVIAN_MOLDAVIA, "mo" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_RUSSIAN_RUSSIA, "ru" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_RUSSIAN_MOLDAVIA, "ru" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_CROATIAN_CROATIA, "hr" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SERBIAN_SERBIA_LATIN, "sr" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SERBIAN_SERBIA_CYRILLIC, "sr" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SLOVAK_SLOVAKIA, "sk" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ALBANIAN_ALBANIA, "sq" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SWEDISH_SWEDEN, "sv" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SWEDISH_FINLAND, "sv" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_THAI_THAILAND, "th" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_TURKISH_TURKEY, "tr" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_URDU_PAKISTAN, "ur" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_INDONESIAN_INDONESIA, "id" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_UKRAINIAN_UKRAINE, "uk" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_BELARUSIAN_BELARUS, "be" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SLOVENE_SLOVENIA, "sl" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ESTONIAN_ESTONIA, "et" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_LATVIAN_LATVIA, "lv" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_LITHUANIAN_LITHUANIA, "lt" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_CLASSIC_LITHUANIAN_LITHUANIA,"lt" },
#ifdef TT_MS_LANGID_MAORI_NEW_ZELAND
/* this seems to be an error that have been dropped */
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_MAORI_NEW_ZEALAND, "mi" },
#endif
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_FARSI_IRAN, "fa" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_VIETNAMESE_VIET_NAM, "vi" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ARMENIAN_ARMENIA, "hy" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_AZERI_AZERBAIJAN_LATIN, "az" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_AZERI_AZERBAIJAN_CYRILLIC, "az" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_BASQUE_SPAIN, "eu" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SORBIAN_GERMANY, "wen" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_MACEDONIAN_MACEDONIA, "mk" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SUTU_SOUTH_AFRICA, "st" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_TSONGA_SOUTH_AFRICA, "ts" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_TSWANA_SOUTH_AFRICA, "tn" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_VENDA_SOUTH_AFRICA, "ven" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_XHOSA_SOUTH_AFRICA, "xh" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ZULU_SOUTH_AFRICA, "zu" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_AFRIKAANS_SOUTH_AFRICA, "af" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_GEORGIAN_GEORGIA, "ka" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_FAEROESE_FAEROE_ISLANDS, "fo" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_HINDI_INDIA, "hi" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_MALTESE_MALTA, "mt" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SAAMI_LAPONIA, "se" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM,"gd" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_IRISH_GAELIC_IRELAND, "ga" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_MALAY_MALAYSIA, "ms" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_MALAY_BRUNEI_DARUSSALAM, "ms" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_KAZAK_KAZAKSTAN, "kk" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SWAHILI_KENYA, "sw" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_UZBEK_UZBEKISTAN_LATIN, "uz" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_UZBEK_UZBEKISTAN_CYRILLIC, "uz" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_TATAR_TATARSTAN, "tt" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_BENGALI_INDIA, "bn" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_PUNJABI_INDIA, "pa" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_GUJARATI_INDIA, "gu" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ORIYA_INDIA, "or" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_TAMIL_INDIA, "ta" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_TELUGU_INDIA, "te" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_KANNADA_INDIA, "kn" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_MALAYALAM_INDIA, "ml" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ASSAMESE_INDIA, "as" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_MARATHI_INDIA, "mr" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SANSKRIT_INDIA, "sa" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_KONKANI_INDIA, "kok" },
/* new as of 2001-01-01 */
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ARABIC_GENERAL, "ar" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_CHINESE_GENERAL, "zh" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ENGLISH_GENERAL, "en" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_FRENCH_WEST_INDIES, "fr" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_FRENCH_REUNION, "fr" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_FRENCH_CONGO, "fr" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_FRENCH_SENEGAL, "fr" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_FRENCH_CAMEROON, "fr" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_FRENCH_COTE_D_IVOIRE, "fr" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_FRENCH_MALI, "fr" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_BOSNIAN_BOSNIA_HERZEGOVINA,"bs" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_URDU_INDIA, "ur" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_TAJIK_TAJIKISTAN, "tg" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_YIDDISH_GERMANY, "yi" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_KIRGHIZ_KIRGHIZSTAN, "ky" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_TURKMEN_TURKMENISTAN, "tk" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_MONGOLIAN_MONGOLIA, "mn" },
/* the following seems to be inconsistent;
here is the current "official" way: */
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_TIBETAN_BHUTAN, "bo" },
/* and here is what is used by Passport SDK */
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_TIBETAN_CHINA, "bo" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_DZONGHKA_BHUTAN, "dz" },
/* end of inconsistency */
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_WELSH_WALES, "cy" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_KHMER_CAMBODIA, "km" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_LAO_LAOS, "lo" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_BURMESE_MYANMAR, "my" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_GALICIAN_SPAIN, "gl" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_MANIPURI_INDIA, "mni" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SINDHI_INDIA, "sd" },
/* the following one is only encountered in Microsoft RTF specification */
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_KASHMIRI_PAKISTAN, "ks" },
/* the following one is not in the Passport list, looks like an omission */
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_KASHMIRI_INDIA, "ks" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_NEPALI_NEPAL, "ne" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_NEPALI_INDIA, "ne" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_FRISIAN_NETHERLANDS, "fy" },
/* new as of 2001-03-01 (from Office Xp) */
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ENGLISH_HONG_KONG, "en" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ENGLISH_INDIA, "en" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ENGLISH_MALAYSIA, "en" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ENGLISH_SINGAPORE, "en" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SYRIAC_SYRIA, "syr" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SINHALESE_SRI_LANKA, "si" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_CHEROKEE_UNITED_STATES, "chr" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_INUKTITUT_CANADA, "iu" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_AMHARIC_ETHIOPIA, "am" },
#if 0
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_TAMAZIGHT_MOROCCO },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_TAMAZIGHT_MOROCCO_LATIN },
#endif
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_PASHTO_AFGHANISTAN, "ps" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_FILIPINO_PHILIPPINES, "phi" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_DHIVEHI_MALDIVES, "div" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_OROMO_ETHIOPIA, "om" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_TIGRIGNA_ETHIOPIA, "ti" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_TIGRIGNA_ERYTHREA, "ti" },
/* New additions from Windows Xp/Passport SDK 2001-11-10. */
/* don't ask what this one means... It is commented out currently. */
#if 0
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_GREEK_GREECE2 },
#endif
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SPANISH_UNITED_STATES, "es" },
/* The following two IDs blatantly violate MS specs by using a */
/* sublanguage >,. */
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SPANISH_LATIN_AMERICA, "es" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_FRENCH_NORTH_AFRICA, "fr" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_FRENCH_MOROCCO, "fr" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_FRENCH_HAITI, "fr" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_BENGALI_BANGLADESH, "bn" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_PUNJABI_ARABIC_PAKISTAN, "ar" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_MONGOLIAN_MONGOLIA_MONGOLIAN,"mn" },
#if 0
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_EDO_NIGERIA },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_FULFULDE_NIGERIA },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_IBIBIO_NIGERIA },
#endif
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_HAUSA_NIGERIA, "ha" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_YORUBA_NIGERIA, "yo" },
/* language codes from, to, are (still) unknown. */
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_IGBO_NIGERIA, "ibo" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_KANURI_NIGERIA, "kau" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_GUARANI_PARAGUAY, "gn" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_HAWAIIAN_UNITED_STATES, "haw" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_LATIN, "la" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SOMALI_SOMALIA, "so" },
#if 0
/* Note: Yi does not have a (proper) ISO 639-2 code, since it is mostly */
/* not written (but OTOH the peculiar writing system is worth */
/* studying). */
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_YI_CHINA },
#endif
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_PAPIAMENTU_NETHERLANDS_ANTILLES,"pap" },
};
static const char *
FcSfntNameLanguage (FT_SfntName *sname)
{
int i;
FT_UShort platform_id = sname->platform_id;
FT_UShort language_id = sname->language_id;
for (i = 0; i < G_N_ELEMENTS (ftLanguage); i++)
if (ftLanguage[i].platform_id == platform_id &&
(ftLanguage[i].language_id == TT_LANGUAGE_DONT_CARE ||
ftLanguage[i].language_id == language_id))
{
if (ftLanguage[i].lang[0] == '\0')
return NULL;
else
return ftLanguage[i].lang;
}
return NULL;
}
static char *
FcSfntNameTranscode (FT_SfntName *name)
{
int i;
const char *fromcode;
for (i = 0; i < G_N_ELEMENTS (ftEncoding); i++)
if (ftEncoding[i].platform_id == name->platform_id &&
(ftEncoding[i].encoding_id == TT_ENCODING_DONT_CARE ||
ftEncoding[i].encoding_id == name->encoding_id))
break;
if (i == G_N_ELEMENTS (ftEncoding))
return NULL;
fromcode = ftEncoding[i].fromcode;
return g_convert ((const char *)name->string, name->string_len, "UTF-8", fromcode, NULL, NULL, NULL);
}
static char *
get_sfnt_name (FT_Face ft_face,
guint nameid)
{
guint count;
guint i, j;
const char * const *langs = g_get_language_names ();
char *res = NULL;
guint pos = G_MAXUINT;
count = FT_Get_Sfnt_Name_Count (ft_face);
for (i = 0; i < count; i++)
{
FT_SfntName name;
const char *lang;
if (FT_Get_Sfnt_Name (ft_face, i, &name) != 0)
continue;
if (name.name_id != nameid)
continue;
lang = FcSfntNameLanguage (&name);
for (j = 0; j < pos && langs[j]; j++)
{
if (strcmp (lang, langs[j]) == 0)
{
pos = j;
g_free (res);
res = FcSfntNameTranscode (&name);
}
}
if (pos == 0)
break;
}
return res;
}
static gboolean
is_valid_subfamily_id (guint id)
{
return id == 2 || id == 17 || (255 < id && id < 32768);
}
static void
add_instance (FT_Face ft_face,
FT_MM_Var *ft_mm_var,
FT_Var_Named_Style *ns,
GtkWidget *combo,
int pos)
add_instance (hb_face_t *face,
unsigned int index,
GtkWidget *combo,
int pos)
{
Instance *instance;
int i;
hb_ot_name_id_t name_id;
char name[20];
unsigned int name_len = 20;
instance = g_new0 (Instance, 1);
if (is_valid_subfamily_id (ns->strid))
instance->name = get_sfnt_name (ft_face, ns->strid);
if (!instance->name)
instance->name = g_strdup_printf ("Instance %d", pos);
name_id = hb_ot_var_named_instance_get_subfamily_name_id (face, index);
hb_ot_name_get_utf8 (face, name_id, HB_LANGUAGE_INVALID, &name_len, name);
instance->name = g_strdup (name);
instance->index = index;
g_hash_table_add (instances, instance);
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), instance->name);
instance->n_axes = ft_mm_var->num_axis;
instance->axes = g_new (guint32, ft_mm_var->num_axis);
instance->coords = g_new (float, ft_mm_var->num_axis);
for (i = 0; i < ft_mm_var->num_axis; i++)
{
instance->axes[i] = ft_mm_var->axis[i].tag;
instance->coords[i] = FixedToFloat(ns->coords[i]);
}
}
static void
@@ -1439,6 +901,13 @@ instance_changed (GtkComboBox *combo)
Instance *instance;
Instance ikey;
int i;
unsigned int coords_length;
float *coords = NULL;
hb_ot_var_axis_info_t *ai = NULL;
unsigned int n_axes;
PangoFont *pango_font = NULL;
hb_font_t *hb_font;
hb_face_t *hb_face;
text = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (combo));
if (text[0] == '\0')
@@ -1452,17 +921,29 @@ instance_changed (GtkComboBox *combo)
goto out;
}
for (i = 0; i < instance->n_axes; i++)
pango_font = get_pango_font ();
hb_font = pango_font_get_hb_font (pango_font);
hb_face = hb_font_get_face (hb_font);
n_axes = hb_ot_var_get_axis_infos (hb_face, 0, NULL, NULL);
ai = g_new (hb_ot_var_axis_info_t, n_axes);
hb_ot_var_get_axis_infos (hb_face, 0, &n_axes, ai);
coords = g_new (float, n_axes);
hb_ot_var_named_instance_get_design_coords (hb_face,
instance->index,
&coords_length,
coords);
for (i = 0; i < n_axes; i++)
{
Axis *axis;
Axis akey;
guint32 tag;
gdouble value;
tag = instance->axes[i];
value = instance->coords[i];
value = coords[ai[i].axis_index];
akey.tag = tag;
akey.tag = ai[i].tag;
axis = g_hash_table_lookup (axes, &akey);
if (axis)
{
@@ -1474,17 +955,31 @@ instance_changed (GtkComboBox *combo)
out:
g_free (text);
g_clear_object (&pango_font);
g_free (ai);
g_free (coords);
}
static gboolean
matches_instance (FT_Var_Named_Style *instance,
FT_Fixed *coords,
FT_UInt num_coords)
matches_instance (hb_face_t *hb_face,
unsigned int index,
unsigned int n_axes,
float *coords)
{
FT_UInt i;
float *instance_coords;
unsigned int coords_length;
int i;
for (i = 0; i < num_coords; i++)
if (coords[i] != instance->coords[i])
instance_coords = g_new (float, n_axes);
coords_length = n_axes;
hb_ot_var_named_instance_get_design_coords (hb_face,
index,
&coords_length,
instance_coords);
for (i = 0; i < n_axes; i++)
if (instance_coords[i] != coords[i])
return FALSE;
return TRUE;
@@ -1515,14 +1010,31 @@ add_font_plane (int i)
}
}
/* FIXME: This doesn't work if the font has an avar table */
static float
denorm_coord (hb_ot_var_axis_info_t *axis, int coord)
{
float r = coord / 16384.0;
if (coord < 0)
return axis->default_value + r * (axis->default_value - axis->min_value);
else
return axis->default_value + r * (axis->max_value - axis->default_value);
}
static void
update_font_variations (void)
{
GtkWidget *child, *next;
PangoFont *pango_font;
FT_Face ft_face;
FT_MM_Var *ft_mm_var;
FT_Error ret;
PangoFont *pango_font = NULL;
hb_font_t *hb_font;
hb_face_t *hb_face;
unsigned int n_axes;
hb_ot_var_axis_info_t *ai = NULL;
float *design_coords = NULL;
const int *coords;
unsigned int length;
int i;
child = gtk_widget_get_first_child (variations_grid);
while (child != NULL)
@@ -1538,81 +1050,82 @@ update_font_variations (void)
g_hash_table_remove_all (instances);
pango_font = get_pango_font ();
ft_face = pango_fc_font_lock_face (PANGO_FC_FONT (pango_font)),
hb_font = pango_font_get_hb_font (pango_font);
hb_face = hb_font_get_face (hb_font);
ret = FT_Get_MM_Var (ft_face, &ft_mm_var);
if (ret == 0)
n_axes = hb_ot_var_get_axis_infos (hb_face, 0, NULL, NULL);
if (n_axes == 0)
goto done;
ai = g_new0 (hb_ot_var_axis_info_t, n_axes);
design_coords = g_new (float, n_axes);
hb_ot_var_get_axis_infos (hb_face, 0, &n_axes, ai);
coords = hb_font_get_var_coords_normalized (hb_font, &length);
for (i = 0; i < length; i++)
design_coords[i] = denorm_coord (&ai[i], coords[i]);
if (hb_ot_var_get_named_instance_count (hb_face) > 0)
{
unsigned int i;
FT_Fixed *coords;
GtkWidget *label;
GtkWidget *combo;
coords = g_new (FT_Fixed, ft_mm_var->num_axis);
ret = FT_Get_Var_Design_Coordinates (ft_face, ft_mm_var->num_axis, coords);
label = gtk_label_new ("Instance");
gtk_label_set_xalign (GTK_LABEL (label), 0);
gtk_widget_set_halign (label, GTK_ALIGN_START);
gtk_widget_set_valign (label, GTK_ALIGN_BASELINE);
gtk_grid_attach (GTK_GRID (variations_grid), label, 0, -1, 2, 1);
if (ft_mm_var->num_namedstyles > 0)
combo = gtk_combo_box_text_new ();
gtk_widget_set_valign (combo, GTK_ALIGN_BASELINE);
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "");
for (i = 0; i < hb_ot_var_get_named_instance_count (hb_face); i++)
add_instance (hb_face, i, combo, i);
for (i = 0; i < hb_ot_var_get_named_instance_count (hb_face); i++)
{
GtkWidget *label;
GtkWidget *combo;
label = gtk_label_new ("Instance");
gtk_label_set_xalign (GTK_LABEL (label), 0);
gtk_widget_set_halign (label, GTK_ALIGN_START);
gtk_widget_set_valign (label, GTK_ALIGN_BASELINE);
gtk_grid_attach (GTK_GRID (variations_grid), label, 0, -1, 2, 1);
combo = gtk_combo_box_text_new ();
gtk_widget_set_valign (combo, GTK_ALIGN_BASELINE);
g_signal_connect (combo, "changed", G_CALLBACK (instance_changed), NULL);
gtk_grid_attach (GTK_GRID (variations_grid), combo, 1, -1, 2, 1);
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "");
for (i = 0; i < ft_mm_var->num_namedstyles; i++)
add_instance (ft_face, ft_mm_var, &ft_mm_var->namedstyle[i], combo, i);
for (i = 0; i < ft_mm_var->num_namedstyles; i++)
{
if (matches_instance (&ft_mm_var->namedstyle[i], coords, ft_mm_var->num_axis))
{
gtk_combo_box_set_active (GTK_COMBO_BOX (combo), i + 1);
break;
}
}
instance_combo = combo;
if (matches_instance (hb_face, i, n_axes, design_coords))
{
gtk_combo_box_set_active (GTK_COMBO_BOX (combo), i + 1);
break;
}
}
if (ret == 0)
{
for (i = 0; i < ft_mm_var->num_axis; i++)
add_axis (&ft_mm_var->axis[i], coords[i], i);
gtk_grid_attach (GTK_GRID (variations_grid), combo, 1, -1, 2, 1);
g_signal_connect (combo, "changed", G_CALLBACK (instance_changed), NULL);
instance_combo = combo;
}
add_font_plane (ft_mm_var->num_axis);
}
g_free (coords);
free (ft_mm_var);
}
for (i = 0; i < n_axes; i++)
add_axis (hb_face, &ai[i], design_coords[i], i);
pango_fc_font_unlock_face (PANGO_FC_FONT (pango_font));
g_object_unref (pango_font);
add_font_plane (n_axes);
done:
g_clear_object (&pango_font);
g_free (ai);
g_free (design_coords);
}
static void
font_changed (void)
void
font_features_font_changed (void)
{
update_script_combo ();
update_features ();
update_font_variations ();
}
static void
script_changed (void)
void
font_features_script_changed (void)
{
update_features ();
update_display ();
}
static void
reset_features (void)
void
font_features_reset_features (void)
{
GList *l;
@@ -1657,8 +1170,8 @@ switch_to_label (void)
update_display ();
}
static void
toggle_edit (void)
void
font_features_toggle_edit (void)
{
if (strcmp (gtk_stack_get_visible_child_name (GTK_STACK (stack)), "label") == 0)
switch_to_entry ();
@@ -1666,8 +1179,8 @@ toggle_edit (void)
switch_to_label ();
}
static void
stop_edit (void)
void
font_features_stop_edit (void)
{
g_signal_emit_by_name (edit_toggle, "clicked");
}
@@ -1682,7 +1195,7 @@ entry_key_press (GtkEventController *controller,
if (keyval == GDK_KEY_Escape)
{
gtk_editable_set_text (GTK_EDITABLE (entry), text);
stop_edit ();
font_features_stop_edit ();
return GDK_EVENT_STOP;
}
@@ -1702,14 +1215,6 @@ do_font_features (GtkWidget *do_widget)
builder = gtk_builder_new_from_resource ("/font_features/font-features.ui");
gtk_builder_add_callback_symbol (builder, "update_display", update_display);
gtk_builder_add_callback_symbol (builder, "font_changed", font_changed);
gtk_builder_add_callback_symbol (builder, "script_changed", script_changed);
gtk_builder_add_callback_symbol (builder, "reset", reset_features);
gtk_builder_add_callback_symbol (builder, "stop_edit", G_CALLBACK (stop_edit));
gtk_builder_add_callback_symbol (builder, "toggle_edit", G_CALLBACK (toggle_edit));
gtk_builder_connect_signals (builder, NULL);
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
feature_list = GTK_WIDGET (gtk_builder_get_object (builder, "feature_list"));
label = GTK_WIDGET (gtk_builder_get_object (builder, "label"));
@@ -1826,7 +1331,7 @@ do_font_features (GtkWidget *do_widget)
else
g_hash_table_remove_all (axes);
font_changed ();
font_features_font_changed ();
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed), &window);

View File

@@ -19,8 +19,6 @@
#include "fontplane.h"
#include "gtk.h"
enum {
PROP_0,
PROP_WEIGHT_ADJUSTMENT,

View File

@@ -248,7 +248,6 @@ do_fontrendering (GtkWidget *do_widget)
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));

View File

@@ -165,10 +165,11 @@
</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>
<style>
<class name="linked"/>
</style>
<child>
<object class="GtkRadioButton" id="text_radio">
<property name="draw-indicator">0</property>
@@ -183,7 +184,7 @@
</object>
</child>
<layout>
<property name="left-attach">0</property>
<property name="left-attach">0</property>
<property name="top-attach">3</property>
<property name="column-span">7</property>
</layout>

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);
}

View File

@@ -53,7 +53,6 @@ enum {
PROP_BENCHMARK,
PROP_COUNT,
PROP_FRAMERATE,
PROP_FRAMERATE_STRING,
PROP_UPDATE_DELAY,
NUM_PROPERTIES
};
@@ -289,14 +288,6 @@ gtk_fishbowl_get_property (GObject *object,
g_value_set_double (value, gtk_fishbowl_get_framerate (fishbowl));
break;
case PROP_FRAMERATE_STRING:
{
char *s = g_strdup_printf ("%.2f", gtk_fishbowl_get_framerate (fishbowl));
g_value_set_string (value, s);
g_free (s);
}
break;
case PROP_UPDATE_DELAY:
g_value_set_int64 (value, gtk_fishbowl_get_update_delay (fishbowl));
break;
@@ -350,13 +341,6 @@ gtk_fishbowl_class_init (GtkFishbowlClass *klass)
0,
G_PARAM_READABLE);
props[PROP_FRAMERATE_STRING] =
g_param_spec_string ("framerate-string",
"Framerate as string",
"Framerate as string, with 2 decimals",
NULL,
G_PARAM_READABLE);
props[PROP_UPDATE_DELAY] =
g_param_spec_int64 ("update-delay",
"Update delay",
@@ -508,7 +492,6 @@ gtk_fishbowl_do_update (GtkFishbowl *fishbowl)
priv->framerate = ((int)(priv->framerate * 100))/100.0;
g_object_notify_by_pspec (G_OBJECT (fishbowl), props[PROP_FRAMERATE]);
g_object_notify_by_pspec (G_OBJECT (fishbowl), props[PROP_FRAMERATE_STRING]);
if (!priv->benchmark)
return;

View File

@@ -41,6 +41,7 @@ show_page (GtkTextBuffer *buffer,
gtk_text_buffer_set_text (buffer, "", 0);
gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
gtk_text_buffer_begin_irreversible_action (buffer);
if (page == 1)
{
gtk_text_buffer_insert (buffer, &iter, "Some text to show that simple ", -1);
@@ -73,6 +74,7 @@ show_page (GtkTextBuffer *buffer,
"so that related items of information are connected.\n", -1);
insert_link (buffer, &iter, "Go back", 1);
}
gtk_text_buffer_end_irreversible_action (buffer);
}
/* Looks at all tags covering the position of iter in the text view,
@@ -258,6 +260,7 @@ do_hypertext (GtkWidget *do_widget)
gtk_widget_add_controller (view, controller);
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
gtk_text_buffer_set_enable_undo (buffer, TRUE);
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),

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

@@ -0,0 +1,278 @@
/* Benchmark/Scrolling
*
* This demo scrolls a view with various content.
*/
#include <gtk/gtk.h>
static guint tick_cb;
static GtkAdjustment *hadjustment;
static GtkAdjustment *vadjustment;
static GtkWidget *window = NULL;
static GtkWidget *scrolledwindow;
static int selected;
#define N_WIDGET_TYPES 6
static int hincrement = 5;
static int vincrement = 5;
static gboolean
scroll_cb (GtkWidget *widget,
GdkFrameClock *frame_clock,
gpointer data)
{
double value;
value = gtk_adjustment_get_value (vadjustment);
if (value + vincrement <= gtk_adjustment_get_lower (vadjustment) ||
(value + vincrement >= gtk_adjustment_get_upper (vadjustment) - gtk_adjustment_get_page_size (vadjustment)))
vincrement = - vincrement;
gtk_adjustment_set_value (vadjustment, value + vincrement);
value = gtk_adjustment_get_value (hadjustment);
if (value + hincrement <= gtk_adjustment_get_lower (hadjustment) ||
(value + hincrement >= gtk_adjustment_get_upper (hadjustment) - gtk_adjustment_get_page_size (hadjustment)))
hincrement = - hincrement;
gtk_adjustment_set_value (hadjustment, value + hincrement);
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);
hincrement = 0;
vincrement = 5;
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow),
GTK_POLICY_NEVER,
GTK_POLICY_AUTOMATIC);
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);
hincrement = 0;
vincrement = 5;
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow),
GTK_POLICY_NEVER,
GTK_POLICY_AUTOMATIC);
gtk_container_add (GTK_CONTAINER (scrolledwindow), textview);
}
static void
populate_image (void)
{
GtkWidget *image;
if (!content)
{
GBytes *bytes;
bytes = g_resources_lookup_data ("/sources/font_features.c", 0, NULL);
content = g_bytes_unref_to_data (bytes, &content_len);
}
image = gtk_picture_new_for_resource ("/sliding_puzzle/portland-rose.jpg");
gtk_picture_set_can_shrink (GTK_PICTURE (image), FALSE);
hincrement = 5;
vincrement = 5;
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
gtk_container_add (GTK_CONTAINER (scrolledwindow), image);
}
extern GtkWidget *create_weather_view (void);
static void
populate_list (void)
{
GtkWidget *list;
list = create_weather_view ();
hincrement = 5;
vincrement = 0;
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
gtk_container_add (GTK_CONTAINER (scrolledwindow), list);
}
extern GtkWidget *create_color_grid (void);
static void
populate_grid (void)
{
GtkWidget *list;
list = create_color_grid ();
hincrement = 0;
vincrement = 5;
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
gtk_container_add (GTK_CONTAINER (scrolledwindow), list);
}
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;
case 3:
gtk_window_set_title (GTK_WINDOW (window), "Scrolling a big image");
populate_image ();
break;
case 4:
gtk_window_set_title (GTK_WINDOW (window), "Scrolling a list");
populate_list ();
break;
case 5:
gtk_window_set_title (GTK_WINDOW (window), "Scrolling a grid");
populate_grid ();
break;
default:
g_assert_not_reached ();
}
tick_cb = gtk_widget_add_tick_callback (window, scroll_cb, NULL, NULL);
}
void
iconscroll_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);
}
void
iconscroll_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");
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);
hadjustment = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "hadjustment"));
vadjustment = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "vadjustment"));
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,43 @@
<?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="iconscroll_prev_clicked_cb"/>
</object>
</child>
<child>
<object class="GtkButton">
<property name="icon-name">pan-end-symbolic</property>
<signal name="clicked" handler="iconscroll_next_clicked_cb"/>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow">
<property name="hscrollbar-policy">never</property>
<property name="hadjustment">
<object class="GtkAdjustment" id="hadjustment"/>
</property>
<property name="vadjustment">
<object class="GtkAdjustment" id="vadjustment"/>
</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

@@ -18,6 +18,10 @@
#include "language-names.h"
#ifndef ISO_CODES_PREFIX
#define ISO_CODES_PREFIX "/usr"
#endif
#define ISO_CODES_DATADIR ISO_CODES_PREFIX "/share/xml/iso-codes"
#define ISO_CODES_LOCALESDIR ISO_CODES_PREFIX "/share/locale"

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,200 @@
/* Lists/Application launcher
*
* This demo uses the GtkCoverFlow widget as a fancy application launcher.
*
* It is also a very small introduction to listviews.
*/
#include <gtk/gtk.h>
/* This is the function that creates the #GListModel that we need.
* GTK list widgets need a #GListModel to display, as models support change
* notifications.
* Unfortunately various older APIs do not provide list models, so we create
* our own.
*/
static GListModel *
create_application_list (void)
{
GListStore *store;
GList *apps, *l;
/* We use a #GListStore here, which is a simple array-like list implementation
* for manual management.
* List models need to know what type of data they provide, so we need to
* provide the type here. As we want to do a list of applications, #GAppInfo
* is the object we provide.
*/
store = g_list_store_new (G_TYPE_APP_INFO);
apps = g_app_info_get_all ();
for (l = apps; l; l = l->next)
{
g_list_store_append (store, l->data);
}
g_list_free_full (apps, g_object_unref);
return G_LIST_MODEL (store);
}
/* This is the function we use for setting up new listitems to display.
* We add just a #GtkImage here to display the application's icon as this is just
* a simple demo.
*/
static void
setup_listitem_cb (GtkListItemFactory *factory,
GtkListItem *list_item)
{
GtkWidget *image;
image = gtk_image_new ();
gtk_image_set_icon_size (GTK_IMAGE (image), GTK_ICON_SIZE_LARGE);
gtk_list_item_set_child (list_item, image);
}
/* Here we need to prepare the listitem for displaying its item. We get the
* listitem already set up from the previous function, so we can reuse the
* #GtkImage widget we set up above.
* We get the item - which we know is a #GAppInfo because it comes out of
* the model we set up above, grab its icon and display it.
*/
static void
bind_listitem_cb (GtkListItemFactory *factory,
GtkListItem *list_item)
{
GtkWidget *image;
GAppInfo *app_info;
image = gtk_list_item_get_child (list_item);
app_info = gtk_list_item_get_item (list_item);
gtk_image_set_from_gicon (GTK_IMAGE (image), g_app_info_get_icon (app_info));
}
/* In more complex code, we would also need functions to unbind and teardown
* the listitem, but this is simple code, so the default implementations are
* enough. If we had connected signals, this step would have been necessary.
*
* The #GtkSignalListItemFactory documentation contains more information about
* this step.
*/
/* This function is called whenever an item in the list is activated. This is
* the simple way to allow reacting to the Enter key or double-clicking on a
* listitem.
* Of course, it is possible to use far more complex interactions by turning
* off activation and adding buttons or other widgets in the setup function
* above, but this is a simple demo, so we'll use the simple way.
*/
static void
activate_cb (GtkCoverFlow *coverflow,
guint position,
gpointer unused)
{
GAppInfo *app_info;
GdkAppLaunchContext *context;
GError *error = NULL;
app_info = g_list_model_get_item (gtk_cover_flow_get_model (coverflow), position);
/* Prepare the context for launching the application and launch it. This
* code is explained in detail in the documentation for #GdkAppLaunchContext
* and #GAppInfo.
*/
context = gdk_display_get_app_launch_context (gtk_widget_get_display (GTK_WIDGET (coverflow)));
if (!g_app_info_launch (app_info,
NULL,
G_APP_LAUNCH_CONTEXT (context),
&error))
{
GtkWidget *dialog;
/* And because error handling is important, even a simple demo has it:
* We display an error dialog that something went wrong.
*/
dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (coverflow))),
GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
"Could not launch %s", g_app_info_get_display_name (app_info));
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s", error->message);
g_clear_error (&error);
gtk_widget_show (dialog);
}
g_object_unref (context);
g_object_unref (app_info);
}
static GtkWidget *window = NULL;
GtkWidget *
do_listview_applauncher (GtkWidget *do_widget)
{
if (window == NULL)
{
GtkWidget *coverflow, *sw;;
GListModel *model;
GtkListItemFactory *factory;
/* Create a window and set a few defaults */
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_default_size (GTK_WINDOW (window), 640, 320);
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Application Launcher");
g_signal_connect (window, "destroy",
G_CALLBACK(gtk_widget_destroyed), &window);
/* The #GtkListitemFactory is what is used to create #GtkListItems
* to display the data from the model. So it is absolutely necessary
* to create one.
* We will use a #GtkSignalListItemFactory because it is the simplest
* one to use. Different ones are available for different use cases.
* The most powerful one is #GtkBuilderListItemFactory which uses
* #GtkBuilder .ui files, so it requires little code.
*/
factory = gtk_signal_list_item_factory_new ();
g_signal_connect (factory, "setup", G_CALLBACK (setup_listitem_cb), NULL);
g_signal_connect (factory, "bind", G_CALLBACK (bind_listitem_cb), NULL);
/* Create the list widget here: We use a coverflow widget because it's
* the coolest one. We could just as well use other list widgets such
* as a #GtkListView or a #GtkGridView and the code would look very
* similar.
*/
coverflow = gtk_cover_flow_new_with_factory (factory);
/* We connect the activate signal here. It's the function we defined
* above for launching the selected application.
*/
g_signal_connect (coverflow, "activate", G_CALLBACK (activate_cb), NULL);
/* And of course we need to set the data model. Here we call the function
* we wrote above that gives us the list of applications. Then we set
* it on the coverflow list widget.
* The coverflow will now take items from the model and use the factory
* to create as many listitems as it needs to show itself to the user.
*/
model = create_application_list ();
gtk_cover_flow_set_model (GTK_COVER_FLOW (coverflow), model);
g_object_unref (model);
/* List widgets should always be contained in a #GtkScrolledWindow,
* because otherwise they might get too large or they might not
* be scrollable.
*/
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_container_add (GTK_CONTAINER (window), sw);
gtk_container_add (GTK_CONTAINER (sw), coverflow);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_widget_destroy (window);
return window;
}

View File

@@ -0,0 +1,491 @@
/* Lists/Clocks
*
* This demo displays the time in different timezones.
*
* It is using a GtkGridView.
*
* The goal is to show how to set up expressions that track changes
* in objects and make them update widgets. For that, we create a
* GtkClock object that updates its time every second and then use
* various ways to display that time.
*
* Typically, this will be done using GtkBuilder .ui files with the
* help of the <binding> tag, but this demo shows the code that runs
* behind that.
*/
#include <gtk/gtk.h>
#define GTK_TYPE_CLOCK (gtk_clock_get_type ())
G_DECLARE_FINAL_TYPE (GtkClock, gtk_clock, GTK, CLOCK, GObject)
/* This is our object. It's just a timezone */
typedef struct _GtkClock GtkClock;
struct _GtkClock
{
GObject parent_instance;
/* We allow this to be NULL for the local timezone */
GTimeZone *timezone;
/* Name of the location we're displaying time for */
char *location;
};
enum {
PROP_0,
PROP_LOCATION,
PROP_TIME,
PROP_TIMEZONE,
N_PROPS
};
/* This function returns the current time in the clock's timezone.
* Note that this returns a new object every time, so we need to
* remember to unref it after use. */
static GDateTime *
gtk_clock_get_time (GtkClock *clock)
{
if (clock->timezone)
return g_date_time_new_now (clock->timezone);
else
return g_date_time_new_now_local ();
}
/* Here, we implement the functionality required by the GdkPaintable interface.
* This way we have a trivial way to display an analog clock.
* It also allows demonstrating how to directly use objects in the listview
* later by making this object do something interesting. */
static void
gtk_clock_snapshot (GdkPaintable *paintable,
GdkSnapshot *snapshot,
double width,
double height)
{
GtkClock *self = GTK_CLOCK (paintable);
GDateTime *time;
GskRoundedRect outline;
#define BLACK ((GdkRGBA) { 0, 0, 0, 1 })
/* save/restore() is necessary so we can undo the transforms we start
* out with. */
gtk_snapshot_save (snapshot);
/* First, we move the (0, 0) point to the center of the area so
* we can draw everything relative to it. */
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (width / 2, height / 2));
/* Next we scale it, so that we can pretend that the clock is
* 100px in size. That way, we don't need to do any complicated
* math later.
* We use MIN() here so that we use the smaller dimension for sizing.
* That way we don't overdraw but keep the aspect ratio. */
gtk_snapshot_scale (snapshot, MIN (width, height) / 100.0, MIN (width, height) / 100.0);
/* Now we have a circle with diameter 100px (and radius 50px) that
* has its (0, 0) point at the center.
* Let's draw a simple clock into it. */
time = gtk_clock_get_time (self);
/* First, draw a circle. This is a neat little trick to draw a circle
* without requiring Cairo. */
gsk_rounded_rect_init_from_rect (&outline, &GRAPHENE_RECT_INIT(-50, -50, 100, 100), 50);
gtk_snapshot_append_border (snapshot,
&outline,
(float[4]) { 4, 4, 4, 4 },
(GdkRGBA [4]) { BLACK, BLACK, BLACK, BLACK });
/* Next, draw the hour hand.
* We do this using tranforms again: Instead of computing where the angle points
* to, we just rotate everything and then draw the hand as if if was :00.
* We don't even need to care about am/pm here because rotations just work. */
gtk_snapshot_save (snapshot);
gtk_snapshot_rotate (snapshot, 30 * g_date_time_get_hour (time) + 0.5 * g_date_time_get_minute (time));
gsk_rounded_rect_init_from_rect (&outline, &GRAPHENE_RECT_INIT(-2, -23, 4, 25), 2);
gtk_snapshot_push_rounded_clip (snapshot, &outline);
gtk_snapshot_append_color (snapshot, &BLACK, &outline.bounds);
gtk_snapshot_pop (snapshot);
gtk_snapshot_restore (snapshot);
/* And the same as above for the minute hand. Just make this one longer
* so people can tell the hands apart. */
gtk_snapshot_save (snapshot);
gtk_snapshot_rotate (snapshot, 6 * g_date_time_get_minute (time));
gsk_rounded_rect_init_from_rect (&outline, &GRAPHENE_RECT_INIT(-2, -43, 4, 45), 2);
gtk_snapshot_push_rounded_clip (snapshot, &outline);
gtk_snapshot_append_color (snapshot, &BLACK, &outline.bounds);
gtk_snapshot_pop (snapshot);
gtk_snapshot_restore (snapshot);
/* and finally, the second indicator. */
gtk_snapshot_save (snapshot);
gtk_snapshot_rotate (snapshot, 6 * g_date_time_get_second (time));
gsk_rounded_rect_init_from_rect (&outline, &GRAPHENE_RECT_INIT(-2, -43, 4, 10), 2);
gtk_snapshot_push_rounded_clip (snapshot, &outline);
gtk_snapshot_append_color (snapshot, &BLACK, &outline.bounds);
gtk_snapshot_pop (snapshot);
gtk_snapshot_restore (snapshot);
/* And finally, don't forget to restore the initial save() that we did for
* the initial transformations. */
gtk_snapshot_restore (snapshot);
g_date_time_unref (time);
}
/* Our desired size is 100px. That sounds okay for an analog clock */
static int
gtk_clock_get_intrinsic_width (GdkPaintable *paintable)
{
return 100;
}
static int
gtk_clock_get_intrinsic_height (GdkPaintable *paintable)
{
return 100;
}
/* Initialize the paintable interface. This way we turn our clock objects
* into objects that can be drawn.
* There are more functions to this interface to define desired size,
* but this is enough.
*/
static void
gtk_clock_paintable_init (GdkPaintableInterface *iface)
{
iface->snapshot = gtk_clock_snapshot;
iface->get_intrinsic_width = gtk_clock_get_intrinsic_width;
iface->get_intrinsic_height = gtk_clock_get_intrinsic_height;
}
/* Finally, we define the type. The important part is adding the paintable
* interface, so GTK knows that this object can indeed be drawm.
*/
G_DEFINE_TYPE_WITH_CODE (GtkClock, gtk_clock, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE,
gtk_clock_paintable_init))
static GParamSpec *properties[N_PROPS] = { NULL, };
static void
gtk_clock_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GtkClock *self = GTK_CLOCK (object);
switch (property_id)
{
case PROP_LOCATION:
g_value_set_string (value, self->location);
break;
case PROP_TIME:
g_value_take_boxed (value, gtk_clock_get_time (self));
break;
case PROP_TIMEZONE:
g_value_set_boxed (value, self->timezone);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gtk_clock_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GtkClock *self = GTK_CLOCK (object);
switch (property_id)
{
case PROP_LOCATION:
self->location = g_value_dup_string (value);
break;
case PROP_TIMEZONE:
self->timezone = g_value_dup_boxed (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
/* This is the list of all the ticking clocks */
static GSList *ticking_clocks = NULL;
/* This is the id of the timeout source that is updating all ticking clocks */
static guint ticking_clock_id = 0;
/* Every second, this function is called to tell everybody that the
* clocks are ticking.
*/
static gboolean
gtk_clock_tick (gpointer unused)
{
GSList *l;
for (l = ticking_clocks; l; l = l->next)
{
GtkClock *clock = l->data;
/* We will now return a different value for the time porperty,
* so notify about that.
*/
g_object_notify_by_pspec (G_OBJECT (clock), properties[PROP_TIME]);
/* We will also draw the hands of the clock differently.
* So notify about that, too.
*/
gdk_paintable_invalidate_contents (GDK_PAINTABLE (clock));
}
return G_SOURCE_CONTINUE;
}
static void
gtk_clock_stop_ticking (GtkClock *self)
{
ticking_clocks = g_slist_remove (ticking_clocks, self);
/* If no clock is remaining, stop running the tick updates */
if (ticking_clocks == NULL && ticking_clock_id != 0)
g_clear_handle_id (&ticking_clock_id, g_source_remove);
}
static void
gtk_clock_start_ticking (GtkClock *self)
{
/* if no clock is ticking yet, start */
if (ticking_clock_id == 0)
ticking_clock_id = g_timeout_add_seconds (1, gtk_clock_tick, NULL);
ticking_clocks = g_slist_prepend (ticking_clocks, self);
}
static void
gtk_clock_finalize (GObject *object)
{
GtkClock *self = GTK_CLOCK (object);
gtk_clock_stop_ticking (self);
g_free (self->location);
g_clear_pointer (&self->timezone, g_time_zone_unref);
G_OBJECT_CLASS (gtk_clock_parent_class)->finalize (object);
}
static void
gtk_clock_class_init (GtkClockClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->get_property = gtk_clock_get_property;
gobject_class->set_property = gtk_clock_set_property;
gobject_class->finalize = gtk_clock_finalize;
properties[PROP_LOCATION] =
g_param_spec_string ("location", NULL, NULL, NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
properties[PROP_TIME] =
g_param_spec_boxed ("time", NULL, NULL, G_TYPE_DATE_TIME, G_PARAM_READABLE);
properties[PROP_TIMEZONE] =
g_param_spec_boxed ("timezone", NULL, NULL, G_TYPE_TIME_ZONE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
g_object_class_install_properties (gobject_class, N_PROPS, properties);
}
static void
gtk_clock_init (GtkClock *self)
{
gtk_clock_start_ticking (self);
}
static GtkClock *
gtk_clock_new (const char *location,
GTimeZone *timezone)
{
GtkClock *result;
result = g_object_new (GTK_TYPE_CLOCK,
"location", location,
"timezone", timezone,
NULL);
g_clear_pointer (&timezone, g_time_zone_unref);
return result;
}
static GListModel *
create_clocks_model (void)
{
GListStore *result;
GtkClock *clock;
result = g_list_store_new (GTK_TYPE_CLOCK);
/* local time */
clock = gtk_clock_new ("local", NULL);
g_list_store_append (result, clock);
g_object_unref (clock);
/* UTC time */
clock = gtk_clock_new ("UTC", g_time_zone_new_utc ());
g_list_store_append (result, clock);
g_object_unref (clock);
/* A bunch of timezones with GTK hackers */
clock = gtk_clock_new ("San Francisco", g_time_zone_new ("America/Los_Angeles"));
g_list_store_append (result, clock);
g_object_unref (clock);
clock = gtk_clock_new ("Boston", g_time_zone_new ("America/New_York"));
g_list_store_append (result, clock);
g_object_unref (clock);
clock = gtk_clock_new ("London", g_time_zone_new ("Europe/London"));
g_list_store_append (result, clock);
g_object_unref (clock);
clock = gtk_clock_new ("Berlin", g_time_zone_new ("Europe/Berlin"));
g_list_store_append (result, clock);
g_object_unref (clock);
clock = gtk_clock_new ("Moscow", g_time_zone_new ("Europe/Moscow"));
g_list_store_append (result, clock);
g_object_unref (clock);
clock = gtk_clock_new ("New Delhi", g_time_zone_new ("Asia/Kolkata"));
g_list_store_append (result, clock);
g_object_unref (clock);
clock = gtk_clock_new ("Shanghai", g_time_zone_new ("Asia/Shanghai"));
g_list_store_append (result, clock);
g_object_unref (clock);
return G_LIST_MODEL (result);
}
static char *
convert_time_to_string (GObject *image,
GDateTime *time,
gpointer unused)
{
return g_date_time_format (time, "%x\n%X");
}
/* And this function is the crux for this whole demo.
* It shows how to use expressions to set up bindings.
*/
static void
setup_listitem_cb (GtkListItemFactory *factory,
GtkListItem *list_item)
{
GtkWidget *box, *picture, *location_label, *time_label;
GtkExpression *clock_expression, *expression;
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_list_item_set_child (list_item, box);
/* First, we create an expression that gets us the clock from the listitem:
* 1. Create an expression that gets the list item.
* 2. Use that expression's "item" property to get the clock
*/
expression = gtk_constant_expression_new (GTK_TYPE_LIST_ITEM, list_item);
clock_expression = gtk_property_expression_new (GTK_TYPE_LIST_ITEM, expression, "item");
/* Bind the clock's location to a label.
* This is easy: We just get the "location" property of the clock.
*/
expression = gtk_property_expression_new (GTK_TYPE_CLOCK,
gtk_expression_ref (clock_expression),
"location");
/* Now create the label and bind the expression to it. */
location_label = gtk_label_new (NULL);
gtk_expression_bind (expression, location_label, "label", location_label);
gtk_container_add (GTK_CONTAINER (box), location_label);
/* Here we bind the item itself to a GdkPicture.
* This is simply done by using the clock expression itself.
*/
expression = gtk_expression_ref (clock_expression);
/* Now create the widget and bind the expression to it. */
picture = gtk_picture_new ();
gtk_expression_bind (expression, picture, "paintable", picture);
gtk_container_add (GTK_CONTAINER (box), picture);
/* And finally, everything comes together.
* We create a label for displaying the time as text.
* For that, we need to transform the "GDateTime" of the
* time property into a string so that the label can display it.
*/
expression = gtk_property_expression_new (GTK_TYPE_CLOCK,
gtk_expression_ref (clock_expression),
"time");
expression = gtk_cclosure_expression_new (G_TYPE_STRING,
NULL,
1, (GtkExpression *[1]) { expression },
G_CALLBACK (convert_time_to_string),
NULL, NULL);
/* Now create the label and bind the expression to it. */
time_label = gtk_label_new (NULL);
gtk_expression_bind (expression, time_label, "label", time_label);
gtk_container_add (GTK_CONTAINER (box), time_label);
gtk_expression_unref (clock_expression);
}
static GtkWidget *window = NULL;
GtkWidget *
do_listview_clocks (GtkWidget *do_widget)
{
if (window == NULL)
{
GtkWidget *gridview, *sw;
GtkListItemFactory *factory;
GListModel *model;
GtkNoSelection *selection;
/* This is the normal window setup code every demo does */
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "Clocks");
gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed), &window);
/* List widgets go into a scrolled window. Always. */
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_container_add (GTK_CONTAINER (window), sw);
/* Create the factory that creates the listitems. Because we
* used bindings above during setup, we only need to connect
* to the setup signal.
* The bindings take care of the bind step.
*/
factory = gtk_signal_list_item_factory_new ();
g_signal_connect (factory, "setup", G_CALLBACK (setup_listitem_cb), NULL);
gridview = gtk_grid_view_new_with_factory (factory);
gtk_scrollable_set_hscroll_policy (GTK_SCROLLABLE (gridview), GTK_SCROLL_NATURAL);
gtk_scrollable_set_vscroll_policy (GTK_SCROLLABLE (gridview), GTK_SCROLL_NATURAL);
model = create_clocks_model ();
selection = gtk_no_selection_new (model);
gtk_grid_view_set_model (GTK_GRID_VIEW (gridview), G_LIST_MODEL (selection));
gtk_container_add (GTK_CONTAINER (sw), gridview);
g_object_unref (selection);
g_object_unref (model);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_widget_destroy (window);
return window;
}

View File

@@ -0,0 +1,593 @@
/* Lists/Colors
*
* This demo displays a named colors.
*
* It is using a GtkGridView, and shows
* how to sort the data in various ways.
*
* The dataset used here has 9283 items.
*/
#include <gtk/gtk.h>
#define GTK_TYPE_COLOR (gtk_color_get_type ())
G_DECLARE_FINAL_TYPE (GtkColor, gtk_color, GTK, COLOR, GObject)
/* This is our object. It's just a color */
typedef struct _GtkColor GtkColor;
struct _GtkColor
{
GObject parent_instance;
char *name;
GdkRGBA *color;
int h, s, v;
};
enum {
PROP_0,
PROP_NAME,
PROP_COLOR,
PROP_RED,
PROP_GREEN,
PROP_BLUE,
PROP_HUE,
PROP_SATURATION,
PROP_VALUE,
N_PROPS
};
static void
gtk_color_snapshot (GdkPaintable *paintable,
GdkSnapshot *snapshot,
double width,
double height)
{
GtkColor *self = GTK_COLOR (paintable);
gtk_snapshot_append_color (snapshot, self->color, &GRAPHENE_RECT_INIT (0, 0, width, height));
}
static int
gtk_color_get_intrinsic_width (GdkPaintable *paintable)
{
return 32;
}
static int
gtk_color_get_intrinsic_height (GdkPaintable *paintable)
{
return 32;
}
static void
gtk_color_paintable_init (GdkPaintableInterface *iface)
{
iface->snapshot = gtk_color_snapshot;
iface->get_intrinsic_width = gtk_color_get_intrinsic_width;
iface->get_intrinsic_height = gtk_color_get_intrinsic_height;
}
/*
* Finally, we define the type. The important part is adding the paintable
* interface, so GTK knows that this object can indeed be drawm.
*/
G_DEFINE_TYPE_WITH_CODE (GtkColor, gtk_color, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE,
gtk_color_paintable_init))
static GParamSpec *properties[N_PROPS] = { NULL, };
static void
gtk_color_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GtkColor *self = GTK_COLOR (object);
switch (property_id)
{
case PROP_NAME:
g_value_set_string (value, self->name);
break;
case PROP_COLOR:
g_value_set_boxed (value, self->color);
break;
case PROP_RED:
g_value_set_float (value, self->color->red);
break;
case PROP_GREEN:
g_value_set_float (value, self->color->green);
break;
case PROP_BLUE:
g_value_set_float (value, self->color->blue);
break;
case PROP_HUE:
g_value_set_int (value, self->h);
break;
case PROP_SATURATION:
g_value_set_int (value, self->s);
break;
case PROP_VALUE:
g_value_set_int (value, self->v);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gtk_color_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GtkColor *self = GTK_COLOR (object);
switch (property_id)
{
case PROP_NAME:
self->name = g_value_dup_string (value);
break;
case PROP_COLOR:
self->color = g_value_dup_boxed (value);
break;
case PROP_HUE:
self->h = g_value_get_int (value);
break;
case PROP_SATURATION:
self->s = g_value_get_int (value);
break;
case PROP_VALUE:
self->v = g_value_get_int (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gtk_color_finalize (GObject *object)
{
GtkColor *self = GTK_COLOR (object);
g_free (self->name);
g_clear_pointer (&self->color, gdk_rgba_free);
G_OBJECT_CLASS (gtk_color_parent_class)->finalize (object);
}
static void
gtk_color_class_init (GtkColorClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->get_property = gtk_color_get_property;
gobject_class->set_property = gtk_color_set_property;
gobject_class->finalize = gtk_color_finalize;
properties[PROP_NAME] =
g_param_spec_string ("name", NULL, NULL, NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
properties[PROP_COLOR] =
g_param_spec_boxed ("color", NULL, NULL, GDK_TYPE_RGBA, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
properties[PROP_RED] =
g_param_spec_float ("red", NULL, NULL, 0, 1, 0, G_PARAM_READABLE);
properties[PROP_GREEN] =
g_param_spec_float ("green", NULL, NULL, 0, 1, 0, G_PARAM_READABLE);
properties[PROP_BLUE] =
g_param_spec_float ("blue", NULL, NULL, 0, 1, 0, G_PARAM_READABLE);
properties[PROP_HUE] =
g_param_spec_int ("hue", NULL, NULL, 0, 360, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
properties[PROP_SATURATION] =
g_param_spec_int ("saturation", NULL, NULL, 0, 100, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
properties[PROP_VALUE] =
g_param_spec_int ("value", NULL, NULL, 0, 100, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
g_object_class_install_properties (gobject_class, N_PROPS, properties);
}
static void
gtk_color_init (GtkColor *self)
{
}
static GtkColor *
gtk_color_new (const char *name,
float r, float g, float b,
int h, int s, int v)
{
GtkColor *result;
GdkRGBA color = { r, g, b, 1.0 };
result = g_object_new (GTK_TYPE_COLOR,
"name", name,
"color", &color,
"hue", h,
"saturation", s,
"value", v,
NULL);
return result;
}
static GListModel *
create_colors_model (void)
{
GListStore *result;
GtkColor *color;
GBytes *data;
char **lines;
guint i;
result = g_list_store_new (GTK_TYPE_COLOR);
data = g_resources_lookup_data ("/listview_colors/color.names.txt", 0, NULL);
lines = g_strsplit (g_bytes_get_data (data, NULL), "\n", 0);
for (i = 0; lines[i]; i++)
{
const char *name;
char **fields;
int red, green, blue;
int h, s, v;
if (lines[i][0] == '#' || lines[i][0] == '\0')
continue;
fields = g_strsplit (lines[i], " ", 0);
name = fields[1];
red = atoi (fields[3]);
green = atoi (fields[4]);
blue = atoi (fields[5]);
h = atoi (fields[9]);
s = atoi (fields[10]);
v = atoi (fields[11]);
color = gtk_color_new (name, red / 255., green / 255., blue / 255., h, s, v);
g_list_store_append (result, color);
g_object_unref (color);
g_strfreev (fields);
}
g_strfreev (lines);
g_bytes_unref (data);
return G_LIST_MODEL (result);
}
static char *
get_rgb_markup (gpointer this,
GtkColor *color)
{
if (!color)
return NULL;
return g_strdup_printf ("<b>R:</b> %d <b>G:</b> %d <b>B:</b> %d",
(int)(color->color->red * 255),
(int)(color->color->green * 255),
(int)(color->color->blue * 255));
}
static char *
get_hsv_markup (gpointer this,
GtkColor *color)
{
if (!color)
return NULL;
return g_strdup_printf ("<b>H:</b> %d <b>S:</b> %d <b>V:</b> %d",
color->h,
color->s,
color->v);
}
static void
setup_simple_listitem_cb (GtkListItemFactory *factory,
GtkListItem *list_item)
{
GtkWidget *picture;
GtkExpression *color_expression, *expression;
expression = gtk_constant_expression_new (GTK_TYPE_LIST_ITEM, list_item);
color_expression = gtk_property_expression_new (GTK_TYPE_LIST_ITEM, expression, "item");
picture = gtk_picture_new ();
gtk_widget_set_size_request (picture, 32, 32);
gtk_expression_bind (color_expression, picture, "paintable", NULL);
gtk_list_item_set_child (list_item, picture);
}
static void
setup_listitem_cb (GtkListItemFactory *factory,
GtkListItem *list_item)
{
GtkWidget *box, *picture, *name_label, *rgb_label, *hsv_label;;
GtkExpression *color_expression, *expression;
GtkExpression *params[1];
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_list_item_set_child (list_item, box);
expression = gtk_constant_expression_new (GTK_TYPE_LIST_ITEM, list_item);
color_expression = gtk_property_expression_new (GTK_TYPE_LIST_ITEM, expression, "item");
expression = gtk_property_expression_new (GTK_TYPE_COLOR,
gtk_expression_ref (color_expression),
"name");
name_label = gtk_label_new (NULL);
gtk_expression_bind (expression, name_label, "label", NULL);
gtk_container_add (GTK_CONTAINER (box), name_label);
expression = gtk_expression_ref (color_expression);
picture = gtk_picture_new ();
gtk_expression_bind (expression, picture, "paintable", NULL);
gtk_container_add (GTK_CONTAINER (box), picture);
params[0] = gtk_expression_ref (color_expression);
expression = gtk_cclosure_expression_new (G_TYPE_STRING,
NULL,
1, params,
(GCallback)get_rgb_markup,
NULL, NULL);
rgb_label = gtk_label_new (NULL);
gtk_label_set_use_markup (GTK_LABEL (rgb_label), TRUE);
gtk_expression_bind (expression, rgb_label, "label", NULL);
gtk_container_add (GTK_CONTAINER (box), rgb_label);
params[0] = gtk_expression_ref (color_expression);
expression = gtk_cclosure_expression_new (G_TYPE_STRING,
NULL,
1, params,
(GCallback)get_hsv_markup,
NULL, NULL);
hsv_label = gtk_label_new (NULL);
gtk_label_set_use_markup (GTK_LABEL (hsv_label), TRUE);
gtk_expression_bind (expression, hsv_label, "label", NULL);
gtk_container_add (GTK_CONTAINER (box), hsv_label);
gtk_expression_unref (color_expression);
}
static void
set_title (gpointer item,
const char *title)
{
g_object_set_data (G_OBJECT (item), "title", (gpointer)title);
}
static char *
get_title (gpointer item)
{
return g_strdup ((char *)g_object_get_data (G_OBJECT (item), "title"));
}
static gboolean
set_item (GBinding *binding,
const GValue *from,
GValue *to,
gpointer data)
{
GObject *source = g_binding_get_source (binding);
GListModel *model;
guint selected;
gpointer item;
selected = g_value_get_uint (from);
model = gtk_drop_down_get_model (GTK_DROP_DOWN (source));
item = g_list_model_get_item (model, selected);
g_value_set_object (to, item);
g_clear_object (&item);
return TRUE;
}
GtkWidget *
create_color_grid (void)
{
GtkWidget *gridview;
GtkListItemFactory *factory;
GListModel *model, *selection;
gridview = gtk_grid_view_new ();
gtk_scrollable_set_hscroll_policy (GTK_SCROLLABLE (gridview), GTK_SCROLL_NATURAL);
gtk_scrollable_set_vscroll_policy (GTK_SCROLLABLE (gridview), GTK_SCROLL_NATURAL);
factory = gtk_signal_list_item_factory_new ();
g_signal_connect (factory, "setup", G_CALLBACK (setup_simple_listitem_cb), NULL);
gtk_grid_view_set_factory (GTK_GRID_VIEW (gridview), factory);
g_object_unref (factory);
gtk_grid_view_set_max_columns (GTK_GRID_VIEW (gridview), 24);
gtk_grid_view_set_enable_rubberband (GTK_GRID_VIEW (gridview), TRUE);
model = G_LIST_MODEL (gtk_sort_list_model_new (create_colors_model (), NULL));
selection = G_LIST_MODEL (gtk_multi_selection_new (model));
gtk_grid_view_set_model (GTK_GRID_VIEW (gridview), selection);
g_object_unref (selection);
g_object_unref (model);
return gridview;
}
static GtkWidget *window = NULL;
GtkWidget *
do_listview_colors (GtkWidget *do_widget)
{
if (window == NULL)
{
GtkWidget *header, *gridview, *sw, *box, *dropdown;
GtkListItemFactory *factory;
GListStore *factories;
GListModel *model;
GtkSorter *sorter;
GtkSorter *multi_sorter;
GListStore *sorters;
GtkExpression *expression;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "Colors");
header = gtk_header_bar_new ();
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), TRUE);
gtk_window_set_titlebar (GTK_WINDOW (window), header);
gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
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);
gridview = create_color_grid ();
gtk_container_add (GTK_CONTAINER (sw), gridview);
model = gtk_grid_view_get_model (GTK_GRID_VIEW (gridview));
g_object_get (model, "model", &model, NULL);
sorters = g_list_store_new (GTK_TYPE_SORTER);
sorter = gtk_string_sorter_new (gtk_property_expression_new (GTK_TYPE_COLOR, NULL, "name"));
set_title (sorter, "Name");
g_list_store_append (sorters, sorter);
g_object_unref (sorter);
multi_sorter = gtk_multi_sorter_new ();
sorter = gtk_numeric_sorter_new (gtk_property_expression_new (GTK_TYPE_COLOR, NULL, "red"));
gtk_numeric_sorter_set_sort_order (GTK_NUMERIC_SORTER (sorter), GTK_SORT_DESCENDING);
set_title (sorter, "Red");
g_list_store_append (sorters, sorter);
gtk_multi_sorter_append (GTK_MULTI_SORTER (multi_sorter), sorter);
sorter = gtk_numeric_sorter_new (gtk_property_expression_new (GTK_TYPE_COLOR, NULL, "green"));
gtk_numeric_sorter_set_sort_order (GTK_NUMERIC_SORTER (sorter), GTK_SORT_DESCENDING);
set_title (sorter, "Green");
g_list_store_append (sorters, sorter);
gtk_multi_sorter_append (GTK_MULTI_SORTER (multi_sorter), sorter);
sorter = gtk_numeric_sorter_new (gtk_property_expression_new (GTK_TYPE_COLOR, NULL, "blue"));
gtk_numeric_sorter_set_sort_order (GTK_NUMERIC_SORTER (sorter), GTK_SORT_DESCENDING);
set_title (sorter, "Blue");
g_list_store_append (sorters, sorter);
gtk_multi_sorter_append (GTK_MULTI_SORTER (multi_sorter), sorter);
set_title (multi_sorter, "RGB");
g_list_store_append (sorters, multi_sorter);
g_object_unref (multi_sorter);
multi_sorter = gtk_multi_sorter_new ();
sorter = gtk_numeric_sorter_new (gtk_property_expression_new (GTK_TYPE_COLOR, NULL, "hue"));
gtk_numeric_sorter_set_sort_order (GTK_NUMERIC_SORTER (sorter), GTK_SORT_DESCENDING);
set_title (sorter, "Hue");
g_list_store_append (sorters, sorter);
gtk_multi_sorter_append (GTK_MULTI_SORTER (multi_sorter), sorter);
sorter = gtk_numeric_sorter_new (gtk_property_expression_new (GTK_TYPE_COLOR, NULL, "saturation"));
gtk_numeric_sorter_set_sort_order (GTK_NUMERIC_SORTER (sorter), GTK_SORT_DESCENDING);
set_title (sorter, "Saturation");
g_list_store_append (sorters, sorter);
gtk_multi_sorter_append (GTK_MULTI_SORTER (multi_sorter), sorter);
sorter = gtk_numeric_sorter_new (gtk_property_expression_new (GTK_TYPE_COLOR, NULL, "value"));
gtk_numeric_sorter_set_sort_order (GTK_NUMERIC_SORTER (sorter), GTK_SORT_DESCENDING);
set_title (sorter, "Value");
g_list_store_append (sorters, sorter);
gtk_multi_sorter_append (GTK_MULTI_SORTER (multi_sorter), sorter);
set_title (multi_sorter, "HSV");
g_list_store_append (sorters, multi_sorter);
g_object_unref (multi_sorter);
dropdown = gtk_drop_down_new ();
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
gtk_container_add (GTK_CONTAINER (box), gtk_label_new ("Sort by:"));
gtk_container_add (GTK_CONTAINER (box), dropdown);
gtk_header_bar_pack_end (GTK_HEADER_BAR (header), box);
expression = gtk_cclosure_expression_new (G_TYPE_STRING,
NULL,
0, NULL,
(GCallback)get_title,
NULL, NULL);
gtk_drop_down_set_expression (GTK_DROP_DOWN (dropdown), expression);
gtk_expression_unref (expression);
gtk_drop_down_set_model (GTK_DROP_DOWN (dropdown), G_LIST_MODEL (sorters));
g_object_unref (sorters);
g_object_bind_property_full (dropdown, "selected",
model, "sorter",
G_BINDING_SYNC_CREATE,
set_item, NULL,
NULL, NULL);
factories = g_list_store_new (GTK_TYPE_LIST_ITEM_FACTORY);
factory = gtk_signal_list_item_factory_new ();
g_signal_connect (factory, "setup", G_CALLBACK (setup_simple_listitem_cb), NULL);
set_title (factory, "Colors");
g_list_store_append (factories, factory);
factory = gtk_signal_list_item_factory_new ();
g_signal_connect (factory, "setup", G_CALLBACK (setup_listitem_cb), NULL);
set_title (factory, "Everything");
g_list_store_append (factories, factory);
dropdown = gtk_drop_down_new ();
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
gtk_container_add (GTK_CONTAINER (box), gtk_label_new ("Show:"));
gtk_container_add (GTK_CONTAINER (box), dropdown);
gtk_header_bar_pack_end (GTK_HEADER_BAR (header), box);
expression = gtk_cclosure_expression_new (G_TYPE_STRING,
NULL,
0, NULL,
(GCallback)get_title,
NULL, NULL);
gtk_drop_down_set_expression (GTK_DROP_DOWN (dropdown), expression);
gtk_expression_unref (expression);
gtk_drop_down_set_model (GTK_DROP_DOWN (dropdown), G_LIST_MODEL (factories));
g_object_unref (factories);
g_object_bind_property_full (dropdown, "selected",
gridview, "factory",
G_BINDING_SYNC_CREATE,
set_item, NULL,
NULL, NULL);
g_object_unref (model);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_widget_destroy (window);
return window;
}

View File

@@ -0,0 +1,256 @@
/* Lists/File browser
*
* This demo shows off the different layouts that are quickly achievable
* with GtkListview and 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)
{
}
char *
filebrowser_get_display_name (GObject *object,
GFileInfo *info)
{
if (!info)
return NULL;
return g_strdup (g_file_info_get_attribute_string (info, "standard::display-name"));
}
char *
filebrowser_get_content_type (GObject *object,
GFileInfo *info)
{
if (!info)
return NULL;
return g_strdup (g_file_info_get_attribute_string (info, "standard::content-type"));
}
char *
filebrowser_get_size (GObject *object,
GFileInfo *info)
{
if (!info)
return NULL;
return g_format_size (g_file_info_get_attribute_uint64 (info, "standard::size"));
}
GIcon *
filebrowser_get_icon (GObject *object,
GFileInfo *info)
{
GIcon *icon;
if (info)
icon = G_ICON (g_file_info_get_attribute_object (info, "standard::icon"));
else
icon = NULL;
if (icon)
g_object_ref (icon);
return icon;
}
void
filebrowser_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);
}
void
filebrowser_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;
char *cwd;
builder = gtk_builder_new_from_resource ("/listview_filebrowser/listview_filebrowser.ui");
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 */
cwd = g_get_current_dir ();
file = g_file_new_for_path (cwd);
g_free (cwd);
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,240 @@
<?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">
<property name="child">
<object class="GtkBox">
<child>
<object class="GtkImage">
<binding name="gicon">
<closure type="GIcon" function="filebrowser_get_icon">
<lookup name="item">GtkListItem</lookup>
</closure>
</binding>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="halign">start</property>
<binding name="label">
<closure type="gchararray" function="filebrowser_get_display_name">
<lookup name="item">GtkListItem</lookup>
</closure>
</binding>
</object>
</child>
</object>
</property>
</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">
<property name="child">
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="GtkImage">
<property name="icon-size">large</property>
<binding name="gicon">
<closure type="GIcon" function="filebrowser_get_icon">
<lookup name="item">GtkListItem</lookup>
</closure>
</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">
<closure type="gchararray" function="filebrowser_get_display_name">
<lookup name="item">GtkListItem</lookup>
</closure>
</binding>
</object>
</child>
</object>
</property>
</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">
<property name="child">
<object class="GtkBox">
<child>
<object class="GtkImage">
<property name="icon-size">large</property>
<binding name="gicon">
<closure type="GIcon" function="filebrowser_get_icon">
<lookup name="item">GtkListItem</lookup>
</closure>
</binding>
</object>
</child>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel">
<property name="halign">start</property>
<binding name="label">
<closure type="gchararray" function="filebrowser_get_display_name">
<lookup name="item">GtkListItem</lookup>
</closure>
</binding>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="halign">start</property>
<binding name="label">
<closure type="gchararray" function="filebrowser_get_size">
<lookup name="item">GtkListItem</lookup>
</closure>
</binding>
<style>
<class name="dim-label"/>
</style>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="halign">start</property>
<binding name="label">
<closure type="gchararray" function="filebrowser_get_content_type">
<lookup name="item">GtkListItem</lookup>
</closure>
</binding>
<style>
<class name="dim-label"/>
</style>
</object>
</child>
</object>
</child>
</object>
</property>
</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="filebrowser_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">
<property name="child">
<object class="GtkImage">
<binding name="icon-name">
<lookup type="FileBrowserView" name="icon-name">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
</object>
</property>
</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">
<lookup name="factory" type="FileBrowserView">
<lookup name="selected-item">selected-view</lookup>
</lookup>
</binding>
<binding name="orientation">
<lookup name="orientation" type="FileBrowserView">
<lookup name="selected-item">selected-view</lookup>
</lookup>
</binding>
<signal name="activate" handler="filebrowser_view_activated_cb" object="dirlist" swapped="no"/>
</object>
</child>
</object>
</child>
</object>
</interface>

View File

@@ -0,0 +1,473 @@
/* 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);
}
void
minesweeper_cell_clicked_cb (GtkGridView *gridview,
guint pos,
SweeperGame *game)
{
sweeper_game_reveal_cell (game, pos);
}
void
minesweeper_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");
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,48 @@
<?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="minesweeper_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">
<lookup name="win">game</lookup>
</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">
<lookup name="width">game</lookup>
</binding>
<binding name="min-columns">
<lookup name="width">game</lookup>
</binding>
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="resource">/listview_minesweeper/listview_minesweeper_cell.ui</property>
</object>
</property>
<signal name="activate" handler="minesweeper_cell_clicked_cb" object="game" swapped="no"/>
</object>
</child>
</object>
</interface>

View File

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

View File

@@ -0,0 +1,398 @@
/* Lists/Settings
*
* This demo shows a settings viewer for GSettings.
*
* It demonstrates how to implement support for trees with GtkListView.
*
* It also shows how to set up sorting for columns in a GtkColumnView.
*/
#include <gtk/gtk.h>
/* Create an object that wraps GSettingsSchemaKey because that's a boxed type */
typedef struct _SettingsKey SettingsKey;
struct _SettingsKey
{
GObject parent_instance;
GSettings *settings;
GSettingsSchemaKey *key;
};
enum {
PROP_0,
PROP_NAME,
PROP_SUMMARY,
PROP_DESCRIPTION,
PROP_VALUE,
N_PROPS
};
#define SETTINGS_TYPE_KEY (settings_key_get_type ())
G_DECLARE_FINAL_TYPE (SettingsKey, settings_key, SETTINGS, KEY, GObject);
G_DEFINE_TYPE (SettingsKey, settings_key, G_TYPE_OBJECT);
static GParamSpec *properties[N_PROPS] = { NULL, };
static void
settings_key_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
SettingsKey *self = SETTINGS_KEY (object);
switch (property_id)
{
case PROP_DESCRIPTION:
g_value_set_string (value, g_settings_schema_key_get_description (self->key));
break;
case PROP_NAME:
g_value_set_string (value, g_settings_schema_key_get_name (self->key));
break;
case PROP_SUMMARY:
g_value_set_string (value, g_settings_schema_key_get_summary (self->key));
break;
case PROP_VALUE:
{
GVariant *variant = g_settings_get_value (self->settings, g_settings_schema_key_get_name (self->key));
g_value_take_string (value, g_variant_print (variant, FALSE));
g_variant_unref (variant);
}
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
settings_key_finalize (GObject *object)
{
SettingsKey *self = SETTINGS_KEY (object);
g_object_unref (self->settings);
g_settings_schema_key_unref (self->key);
G_OBJECT_CLASS (settings_key_parent_class)->finalize (object);
}
static void
settings_key_class_init (SettingsKeyClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->finalize = settings_key_finalize;
gobject_class->get_property = settings_key_get_property;
properties[PROP_DESCRIPTION] =
g_param_spec_string ("description", NULL, NULL, NULL, G_PARAM_READABLE);
properties[PROP_NAME] =
g_param_spec_string ("name", NULL, NULL, NULL, G_PARAM_READABLE);
properties[PROP_SUMMARY] =
g_param_spec_string ("summary", NULL, NULL, NULL, G_PARAM_READABLE);
properties[PROP_VALUE] =
g_param_spec_string ("value", NULL, NULL, NULL, G_PARAM_READABLE);
g_object_class_install_properties (gobject_class, N_PROPS, properties);
}
static void
settings_key_init (SettingsKey *self)
{
}
static SettingsKey *
settings_key_new (GSettings *settings,
GSettingsSchemaKey *key)
{
SettingsKey *result = g_object_new (SETTINGS_TYPE_KEY, NULL);
result->settings = g_object_ref (settings);
result->key = g_settings_schema_key_ref (key);
return result;
}
static int
strvcmp (gconstpointer p1,
gconstpointer p2)
{
const char * const *s1 = p1;
const char * const *s2 = p2;
return strcmp (*s1, *s2);
}
static GtkFilter *current_filter;
static gboolean
transform_settings_to_keys (GBinding *binding,
const GValue *from_value,
GValue *to_value,
gpointer data)
{
GtkTreeListRow *treelistrow;
GSettings *settings;
GSettingsSchema *schema;
GListStore *store;
GtkSortListModel *sort_model;
GtkFilterListModel *filter_model;
GtkFilter *filter;
GtkExpression *expression;
char **keys;
guint i;
treelistrow = g_value_get_object (from_value);
if (treelistrow == NULL)
return TRUE;
settings = gtk_tree_list_row_get_item (treelistrow);
g_object_get (settings, "settings-schema", &schema, NULL);
store = g_list_store_new (SETTINGS_TYPE_KEY);
keys = g_settings_schema_list_keys (schema);
for (i = 0; keys[i] != NULL; i++)
{
GSettingsSchemaKey *almost_there = g_settings_schema_get_key (schema, keys[i]);
SettingsKey *finally = settings_key_new (settings, almost_there);
g_list_store_append (store, finally);
g_object_unref (finally);
g_settings_schema_key_unref (almost_there);
}
g_strfreev (keys);
g_settings_schema_unref (schema);
g_object_unref (settings);
sort_model = gtk_sort_list_model_new (G_LIST_MODEL (store),
gtk_column_view_get_sorter (GTK_COLUMN_VIEW (data)));
g_object_unref (store);
expression = gtk_property_expression_new (SETTINGS_TYPE_KEY, NULL, "name");
filter = gtk_string_filter_new ();
gtk_string_filter_set_expression (GTK_STRING_FILTER (filter), expression);
filter_model = gtk_filter_list_model_new (G_LIST_MODEL (sort_model), filter);
gtk_expression_unref (expression);
g_object_unref (sort_model);
g_set_object (&current_filter, filter);
g_object_unref (filter);
g_value_take_object (to_value, filter_model);
return TRUE;
}
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);
}
g_strfreev (schemas);
return G_LIST_MODEL (result);
}
static void
search_enabled (GtkSearchEntry *entry)
{
gtk_editable_set_text (GTK_EDITABLE (entry), "");
}
static void
search_changed (GtkSearchEntry *entry,
gpointer data)
{
const char *text = gtk_editable_get_text (GTK_EDITABLE (entry));
if (current_filter)
gtk_string_filter_set_search (GTK_STRING_FILTER (current_filter), text);
}
static void
stop_search (GtkSearchEntry *entry,
gpointer data)
{
gtk_editable_set_text (GTK_EDITABLE (entry), "");
if (current_filter)
gtk_string_filter_set_search (GTK_STRING_FILTER (current_filter), "");
}
static void
move_column (GtkListView *columns_list, gboolean down)
{
GListModel *columns;
guint position;
GtkColumnViewColumn *selected;
GtkColumnView *view;
columns = gtk_list_view_get_model (columns_list);
position = gtk_single_selection_get_selected (GTK_SINGLE_SELECTION (columns));
selected = gtk_single_selection_get_selected_item (GTK_SINGLE_SELECTION (columns));
view = gtk_column_view_column_get_column_view (selected);
if (down && position + 1 < g_list_model_get_n_items (columns))
position++;
else if (!down && position > 0)
position--;
else
return;
gtk_column_view_insert_column (view, position, selected);
gtk_single_selection_set_selected (GTK_SINGLE_SELECTION (columns), position);
}
static void
move_column_down (GtkListView *columns_list)
{
move_column (columns_list, TRUE);
}
static void
move_column_up (GtkListView *columns_list)
{
move_column (columns_list, FALSE);
}
static void
column_visible_toggled (GtkListItem *item, GtkToggleButton *button)
{
GtkColumnViewColumn *column = gtk_list_item_get_item (item);
gtk_column_view_column_set_visible (column, gtk_toggle_button_get_active (button));
}
static GtkWidget *window = NULL;
GtkWidget *
do_listview_settings (GtkWidget *do_widget)
{
if (window == NULL)
{
GtkWidget *listview, *columnview;
GListModel *model;
GtkTreeListModel *treemodel;
GtkSingleSelection *selection;
GtkBuilderScope *scope;
GtkBuilder *builder;
GtkColumnViewColumn *name_column;
GtkSorter *sorter;
GtkWidget *menubutton, *popover;
GtkWidget *columns_list;
g_type_ensure (SETTINGS_TYPE_KEY);
scope = gtk_builder_cscope_new ();
gtk_builder_cscope_add_callback_symbol (GTK_BUILDER_CSCOPE (scope), "search_enabled", (GCallback)search_enabled);
gtk_builder_cscope_add_callback_symbol (GTK_BUILDER_CSCOPE (scope), "search_changed", (GCallback)search_changed);
gtk_builder_cscope_add_callback_symbol (GTK_BUILDER_CSCOPE (scope), "stop_search", (GCallback)stop_search);
gtk_builder_cscope_add_callback_symbol (GTK_BUILDER_CSCOPE (scope), "move_column_down", (GCallback)move_column_down);
gtk_builder_cscope_add_callback_symbol (GTK_BUILDER_CSCOPE (scope), "move_column_up", (GCallback)move_column_up);
gtk_builder_cscope_add_callback_symbol (GTK_BUILDER_CSCOPE (scope), "column_visible_toggled", (GCallback)column_visible_toggled);
builder = gtk_builder_new ();
gtk_builder_set_scope (builder, scope);
{
g_autoptr(GError) error = NULL;
gtk_builder_add_from_resource (builder, "/listview_settings/listview_settings.ui", &error);
if (error)
g_warning ("%s", error->message);
}
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);
listview = GTK_WIDGET (gtk_builder_get_object (builder, "listview"));
columnview = GTK_WIDGET (gtk_builder_get_object (builder, "columnview"));
model = create_settings_model (NULL, NULL);
treemodel = gtk_tree_list_model_new (FALSE,
model,
TRUE,
create_settings_model,
NULL,
NULL);
selection = gtk_single_selection_new (G_LIST_MODEL (treemodel));
g_object_bind_property_full (selection, "selected-item",
columnview, "model",
G_BINDING_SYNC_CREATE,
transform_settings_to_keys,
NULL,
columnview, NULL);
gtk_list_view_set_model (GTK_LIST_VIEW (listview), G_LIST_MODEL (selection));
g_object_unref (selection);
g_object_unref (treemodel);
g_object_unref (model);
name_column = GTK_COLUMN_VIEW_COLUMN (gtk_builder_get_object (builder, "name_column"));
sorter = gtk_string_sorter_new (gtk_property_expression_new (SETTINGS_TYPE_KEY, NULL, "name"));
gtk_column_view_column_set_sorter (name_column, sorter);
g_object_unref (sorter);
menubutton = GTK_WIDGET (gtk_builder_get_object (builder, "menubutton"));
popover = GTK_WIDGET (gtk_builder_get_object (builder, "column_popover"));
gtk_menu_button_set_popover (GTK_MENU_BUTTON (menubutton), popover);
columns_list = GTK_WIDGET (gtk_builder_get_object (builder, "columns_list"));
model = G_LIST_MODEL (gtk_single_selection_new (gtk_column_view_get_columns (GTK_COLUMN_VIEW (columnview))));
gtk_list_view_set_model (GTK_LIST_VIEW (columns_list), model);
g_object_unref (model);
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,262 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow" id="window">
<property name="title" translatable="yes">Settings</property>
<property name="default-width">640</property>
<property name="default-height">480</property>
<child type="titlebar">
<object class="GtkHeaderBar">
<property name="show-title-buttons">1</property>
<child type="end">
<object class="GtkMenuButton" id="menubutton">
<property name="icon-name">open-menu-symbolic</property>
</object>
</child>
<child type="end">
<object class="GtkToggleButton" id="search_button">
<property name="icon-name">system-search-symbolic</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkPaned">
<property name="position">300</property>
<child>
<object class="GtkScrolledWindow">
<child>
<object class="GtkListView" id="listview">
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="bytes"><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<property name="child">
<object class="GtkTreeExpander" id="expander">
<binding name="list-row">
<lookup name="item">GtkListItem</lookup>
</binding>
<property name="child">
<object class="GtkLabel">
<property name="xalign">0</property>
<binding name="label">
<lookup name="schema" type="GSettings">
<lookup name="item">expander</lookup>
</lookup>
</binding>
</object>
</property>
</object>
</property>
</template>
</interface>
]]></property>
</object>
</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="GtkSearchBar">
<property name="search-mode-enabled" bind-source="search_button" bind-property="active" bind-flags="bidirectional"/>
<signal name="notify::search-mode-enabled" handler="search_enabled" object="entry"/>
<child>
<object class="GtkSearchEntry" id="entry">
<signal name="search-changed" handler="search_changed"/>
<signal name="stop-search" handler="stop_search"/>
</object>
</child>
</object>
</child>
<child>
<object class="GtkScrolledWindow">
<property name="expand">1</property>
<child>
<object class="GtkColumnView" id="columnview">
<child>
<object class="GtkColumnViewColumn" id="name_column">
<property name="title">Name</property>
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="bytes"><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<property name="child">
<object class="GtkLabel">
<property name="xalign">0</property>
<binding name="label">
<lookup name="name" type="SettingsKey">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
</object>
</property>
</template>
</interface>
]]></property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkColumnViewColumn" id="value_column">
<property name="title">Value</property>
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="bytes"><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<property name="child">
<object class="GtkLabel">
<property name="xalign">0</property>
<binding name="label">
<lookup name="value" type="SettingsKey">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
</object>
</property>
</template>
</interface>
]]></property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkColumnViewColumn" id="summary_column">
<property name="title">Summary</property>
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="bytes"><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<property name="child">
<object class="GtkLabel">
<property name="xalign">0</property>
<binding name="label">
<lookup name="summary" type="SettingsKey">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
</object>
</property>
</template>
</interface>
]]></property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkColumnViewColumn" id="description_column">
<property name="title">Description</property>
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="bytes"><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<property name="child">
<object class="GtkLabel">
<property name="xalign">0</property>
<binding name="label">
<lookup name="description" type="SettingsKey">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
</object>
</property>
</template>
</interface>
]]></property>
</object>
</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
<object class="GtkPopover" id="column_popover">
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="GtkListView" id="columns_list">
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="bytes"><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<property name="child">
<object class="GtkBox">
<property name="spacing">10</property>
<child>
<object class="GtkCheckButton">
<signal name="toggled" handler="column_visible_toggled" object="GtkListItem"/>
<binding name="active">
<lookup name="visible" type="GtkColumnViewColumn">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="xalign">0</property>
<property name="label">label</property>
<binding name="label">
<lookup name="title" type="GtkColumnViewColumn">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
</object>
</child>
</object>
</property>
</template>
</interface>
]]></property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkBox">
<property name="halign">center</property>
<style>
<class name="linked"/>
</style>
<child>
<object class="GtkButton">
<property name="icon-name">go-down-symbolic</property>
<signal name="clicked" handler="move_column_down" object="columns_list"/>
</object>
</child>
<child>
<object class="GtkButton">
<property name="icon-name">go-up-symbolic</property>
<signal name="clicked" handler="move_column_up" object="columns_list"/>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>

View File

@@ -0,0 +1,329 @@
/* 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.
*
* The dataset used here has 70000 items.
*/
#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_list_item_set_child (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_list_item_get_child (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 *
create_weather_view (void)
{
GtkWidget *listview;
GListModel *model, *selection;
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);
return listview;
}
GtkWidget *
do_listview_weather (GtkWidget *do_widget)
{
if (window == NULL)
{
GtkWidget *listview, *sw;;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
gtk_window_set_title (GTK_WINDOW (window), "Weather");
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 = create_weather_view ();
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,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<property name="child">
<object class="GtkTreeExpander" id="expander">
<binding name="list-row">
<lookup name="item">GtkListItem</lookup>
</binding>
<property name="child">
<object class="GtkLabel">
<property name="halign">start</property>
<binding name="label">
<lookup name="title" type="GtkDemo">
<lookup name="item">expander</lookup>
</lookup>
</binding>
</object>
</property>
</object>
</property>
</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);
@@ -748,6 +784,9 @@ load_file (const gchar *demoname,
source_buffer = gtk_text_buffer_new (NULL);
gtk_text_buffer_begin_irreversible_action (info_buffer);
gtk_text_buffer_begin_irreversible_action (source_buffer);
resource_filename = g_strconcat ("/sources/", filename, NULL);
bytes = g_resources_lookup_data (resource_filename, 0, &err);
g_free (resource_filename);
@@ -880,89 +919,82 @@ load_file (const gchar *demoname,
fontify (source_buffer);
gtk_text_buffer_end_irreversible_action (source_buffer);
gtk_text_view_set_buffer (GTK_TEXT_VIEW (source_view), source_buffer);
g_object_unref (source_buffer);
gtk_text_buffer_end_irreversible_action (info_buffer);
gtk_text_view_set_buffer (GTK_TEXT_VIEW (info_view), info_buffer);
g_object_unref (info_buffer);
}
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 +1014,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 +1040,36 @@ scrollbar_popup (GtkWidget *scrollbar, GtkWidget *menu)
return TRUE;
}
void
main_activate_cb (GtkListView *listview,
guint position,
gpointer user_data)
{
GtkTreeListRow *row = g_list_model_get_item (gtk_list_view_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_from_resource (builder, "/ui/main.ui", &error);
if (error != NULL)
{
g_critical ("%s", error->message);
exit (1);
}
builder = gtk_builder_new_from_resource ("/ui/main.ui");
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 +1079,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 +1098,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_list_view_set_model (GTK_LIST_VIEW (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 +1127,7 @@ auto_quit (gpointer data)
static void
list_demos (void)
{
Demo *d, *c;
DemoData *d, *c;
d = gtk_demos;
@@ -1135,7 +1154,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="GtkListView" id="listview">
<signal name="activate" handler="main_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

@@ -29,8 +29,10 @@ source_toggled (GtkToggleButton *button)
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
gtk_text_buffer_get_bounds (buffer, &start, &end);
gtk_text_buffer_begin_irreversible_action (buffer);
gtk_text_buffer_delete (buffer, &start, &end);
gtk_text_buffer_insert_markup (buffer, &start, markup, -1);
gtk_text_buffer_end_irreversible_action (buffer);
g_free (markup);
gtk_stack_set_visible_child_name (GTK_STACK (stack), "formatted");
@@ -106,11 +108,15 @@ do_markup (GtkWidget *do_widget)
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
gtk_text_buffer_get_start_iter (buffer, &iter);
gtk_text_buffer_begin_irreversible_action (buffer);
gtk_text_buffer_insert_markup (buffer, &iter, markup, -1);
gtk_text_buffer_end_irreversible_action (buffer);
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view2));
gtk_text_buffer_get_start_iter (buffer, &iter);
gtk_text_buffer_begin_irreversible_action (buffer);
gtk_text_buffer_insert (buffer, &iter, markup, -1);
gtk_text_buffer_end_irreversible_action (buffer);
g_bytes_unref (bytes);

View File

@@ -3,6 +3,7 @@
demos = files([
'application_demo.c',
'assistant.c',
'awardview.c',
'builder.c',
'changedisplay.c',
'clipboard.c',
@@ -22,8 +23,8 @@ demos = files([
'drawingarea.c',
'dnd.c',
'editable_cells.c',
'entry_buffer.c',
'entry_completion.c',
'entry_undo.c',
'expander.c',
'filtermodel.c',
'fishbowl.c',
@@ -34,6 +35,7 @@ demos = files([
'glarea.c',
'headerbar.c',
'hypertext.c',
'iconscroll.c',
'iconview.c',
'iconview_edit.c',
'images.c',
@@ -42,6 +44,13 @@ demos = files([
'listbox.c',
'flowbox.c',
'list_store.c',
'listview_applauncher.c',
'listview_clocks.c',
'listview_colors.c',
'listview_filebrowser.c',
'listview_minesweeper.c',
'listview_settings.c',
'listview_weather.c',
'markup.c',
'menus.c',
'modelbutton.c',
@@ -72,6 +81,7 @@ demos = files([
'tabs.c',
'tagged_entry.c',
'textmask.c',
'textundo.c',
'textview.c',
'textscroll.c',
'themes.c',
@@ -84,6 +94,7 @@ demos = files([
gtkdemo_deps = [ libgtk_dep, ]
extra_demo_sources = files(['main.c',
'award.c',
'gtkfishbowl.c',
'fontplane.c',
'gtkgears.c',
@@ -94,7 +105,7 @@ extra_demo_sources = files(['main.c',
if harfbuzz_dep.found() and pangoft_dep.found()
demos += files('font_features.c')
extra_demo_sources += files(['script-names.c', 'language-names.c'])
gtkdemo_deps += [ harfbuzz_dep, ]
gtkdemo_deps += [ harfbuzz_dep, epoxy_dep ]
endif
if os_unix

View File

@@ -14,8 +14,8 @@
#include <gtk/gtk.h>
static void
tool_clicked (GtkButton *button)
void
modelbutton_tool_clicked (GtkButton *button)
{
gboolean active;
@@ -40,8 +40,6 @@ do_modelbutton (GtkWidget *do_widget)
GActionGroup *actions;
builder = gtk_builder_new_from_resource ("/modelbutton/modelbutton.ui");
gtk_builder_add_callback_symbol (builder, "tool_clicked", G_CALLBACK (tool_clicked));
gtk_builder_connect_signals (builder, NULL);
window = GTK_WIDGET (gtk_builder_get_object (builder, "window1"));
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));

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>
@@ -119,21 +101,21 @@
<object class="GtkModelButton">
<property name="text">Hammer</property>
<property name="role">check</property>
<signal name="clicked" handler="tool_clicked"/>
<signal name="clicked" handler="modelbutton_tool_clicked"/>
</object>
</child>
<child>
<object class="GtkModelButton">
<property name="text">Screwdriver</property>
<property name="role">check</property>
<signal name="clicked" handler="tool_clicked"/>
<signal name="clicked" handler="modelbutton_tool_clicked"/>
</object>
</child>
<child>
<object class="GtkModelButton">
<property name="text">Drill</property>
<property name="role">check</property>
<signal name="clicked" handler="tool_clicked"/>
<signal name="clicked" handler="modelbutton_tool_clicked"/>
</object>
</child>
</object>

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

@@ -69,7 +69,6 @@ do_revealer (GtkWidget *do_widget)
GtkBuilder *builder;
builder = gtk_builder_new_from_resource ("/revealer/revealer.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));

View File

@@ -18,7 +18,6 @@ do_scale (GtkWidget *do_widget)
GtkBuilder *builder;
builder = gtk_builder_new_from_resource ("/scale/scale.ui");
gtk_builder_connect_signals (builder, NULL);
window = GTK_WIDGET (gtk_builder_get_object (builder, "window1"));
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));

View File

@@ -75,11 +75,11 @@
<property name="adjustment">adjustment2</property>
<property name="hexpand">1</property>
<marks>
<mark value="0" position="bottom"/>
<mark value="1" position="bottom"/>
<mark value="2" position="bottom"/>
<mark value="3" position="bottom"/>
<mark value="4" position="bottom"/>
<mark value="0" position="bottom"></mark>
<mark value="1" position="bottom"></mark>
<mark value="2" position="bottom"></mark>
<mark value="3" position="bottom"></mark>
<mark value="4" position="bottom"></mark>
</marks>
<accessibility>
<relation type="labelled-by" target="label_marks"/>
@@ -115,11 +115,11 @@
<relation type="labelled-by" target="label_discrete"/>
</accessibility>
<marks>
<mark value="0" position="bottom"/>
<mark value="1" position="bottom"/>
<mark value="2" position="bottom"/>
<mark value="3" position="bottom"/>
<mark value="4" position="bottom"/>
<mark value="0" position="bottom"></mark>
<mark value="1" position="bottom"></mark>
<mark value="2" position="bottom"></mark>
<mark value="3" position="bottom"></mark>
<mark value="4" position="bottom"></mark>
</marks>
<layout>
<property name="left-attach">1</property>

View File

@@ -25,44 +25,44 @@ show_shortcuts (GtkWidget *window,
g_object_unref (builder);
}
static void
builder_shortcuts (GtkWidget *window)
void
shortcuts_builder_shortcuts (GtkWidget *window)
{
show_shortcuts (window, "shortcuts-builder", NULL);
}
static void
gedit_shortcuts (GtkWidget *window)
void
shortcuts_gedit_shortcuts (GtkWidget *window)
{
show_shortcuts (window, "shortcuts-gedit", NULL);
}
static void
clocks_shortcuts (GtkWidget *window)
void
shortcuts_clocks_shortcuts (GtkWidget *window)
{
show_shortcuts (window, "shortcuts-clocks", NULL);
}
static void
clocks_shortcuts_stopwatch (GtkWidget *window)
void
shortcuts_clocks_shortcuts_stopwatch (GtkWidget *window)
{
show_shortcuts (window, "shortcuts-clocks", "stopwatch");
}
static void
boxes_shortcuts (GtkWidget *window)
void
shortcuts_boxes_shortcuts (GtkWidget *window)
{
show_shortcuts (window, "shortcuts-boxes", NULL);
}
static void
boxes_shortcuts_wizard (GtkWidget *window)
void
shortcuts_boxes_shortcuts_wizard (GtkWidget *window)
{
show_shortcuts (window, "shortcuts-boxes", "wizard");
}
static void
boxes_shortcuts_display (GtkWidget *window)
void
shortcuts_boxes_shortcuts_display (GtkWidget *window)
{
show_shortcuts (window, "shortcuts-boxes", "display");
}
@@ -86,16 +86,6 @@ do_shortcuts (GtkWidget *do_widget)
GtkBuilder *builder;
builder = gtk_builder_new_from_resource ("/shortcuts/shortcuts.ui");
gtk_builder_add_callback_symbols (builder,
"builder_shortcuts", G_CALLBACK (builder_shortcuts),
"gedit_shortcuts", G_CALLBACK (gedit_shortcuts),
"clocks_shortcuts", G_CALLBACK (clocks_shortcuts),
"clocks_shortcuts_stopwatch", G_CALLBACK (clocks_shortcuts_stopwatch),
"boxes_shortcuts", G_CALLBACK (boxes_shortcuts),
"boxes_shortcuts_wizard", G_CALLBACK (boxes_shortcuts_wizard),
"boxes_shortcuts_display", G_CALLBACK (boxes_shortcuts_display),
NULL);
gtk_builder_connect_signals (builder, NULL);
window = GTK_WIDGET (gtk_builder_get_object (builder, "window1"));
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));

View File

@@ -10,43 +10,43 @@
<child>
<object class="GtkButton">
<property name="label">Builder</property>
<signal name="clicked" handler="builder_shortcuts" swapped="1" object="window1"/>
<signal name="clicked" handler="shortcuts_builder_shortcuts" swapped="1" object="window1"/>
</object>
</child>
<child>
<object class="GtkButton">
<property name="label">GEdit</property>
<signal name="clicked" handler="gedit_shortcuts" swapped="1" object="window1"/>
<signal name="clicked" handler="shortcuts_gedit_shortcuts" swapped="1" object="window1"/>
</object>
</child>
<child>
<object class="GtkButton">
<property name="label">Clocks - All</property>
<signal name="clicked" handler="clocks_shortcuts" swapped="1" object="window1"/>
<signal name="clicked" handler="shortcuts_clocks_shortcuts" swapped="1" object="window1"/>
</object>
</child>
<child>
<object class="GtkButton">
<property name="label">Clocks - Stopwatch</property>
<signal name="clicked" handler="clocks_shortcuts_stopwatch" swapped="1" object="window1"/>
<signal name="clicked" handler="shortcuts_clocks_shortcuts_stopwatch" swapped="1" object="window1"/>
</object>
</child>
<child>
<object class="GtkButton">
<property name="label">Boxes</property>
<signal name="clicked" handler="boxes_shortcuts" swapped="1" object="window1"/>
<signal name="clicked" handler="shortcuts_boxes_shortcuts" swapped="1" object="window1"/>
</object>
</child>
<child>
<object class="GtkButton">
<property name="label">Boxes - Wizard</property>
<signal name="clicked" handler="boxes_shortcuts_wizard" swapped="1" object="window1"/>
<signal name="clicked" handler="shortcuts_boxes_shortcuts_wizard" swapped="1" object="window1"/>
</object>
</child>
<child>
<object class="GtkButton">
<property name="label">Boxes - Display</property>
<signal name="clicked" handler="boxes_shortcuts_display" swapped="1" object="window1"/>
<signal name="clicked" handler="shortcuts_boxes_shortcuts_display" swapped="1" object="window1"/>
</object>
</child>
</object>

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

@@ -11,9 +11,9 @@
#include <math.h>
#include <stdlib.h>
static gint
hex_spin_input (GtkSpinButton *spin_button,
gdouble *new_val)
gint
spinbutton_hex_spin_input (GtkSpinButton *spin_button,
gdouble *new_val)
{
const gchar *buf;
gchar *err;
@@ -28,8 +28,8 @@ hex_spin_input (GtkSpinButton *spin_button,
return TRUE;
}
static gint
hex_spin_output (GtkSpinButton *spin_button)
gint
spinbutton_hex_spin_output (GtkSpinButton *spin_button)
{
GtkAdjustment *adjustment;
gchar *buf;
@@ -48,9 +48,9 @@ hex_spin_output (GtkSpinButton *spin_button)
return TRUE;
}
static gint
time_spin_input (GtkSpinButton *spin_button,
gdouble *new_val)
gint
spinbutton_time_spin_input (GtkSpinButton *spin_button,
gdouble *new_val)
{
const gchar *text;
gchar **str;
@@ -87,8 +87,8 @@ time_spin_input (GtkSpinButton *spin_button,
return TRUE;
}
static gint
time_spin_output (GtkSpinButton *spin_button)
gint
spinbutton_time_spin_output (GtkSpinButton *spin_button)
{
GtkAdjustment *adjustment;
gchar *buf;
@@ -121,9 +121,9 @@ static gchar *month[12] = {
"December"
};
static gint
month_spin_input (GtkSpinButton *spin_button,
gdouble *new_val)
gint
spinbutton_month_spin_input (GtkSpinButton *spin_button,
gdouble *new_val)
{
gint i;
gchar *tmp1, *tmp2;
@@ -150,8 +150,8 @@ month_spin_input (GtkSpinButton *spin_button,
return TRUE;
}
static gint
month_spin_output (GtkSpinButton *spin_button)
gint
spinbutton_month_spin_output (GtkSpinButton *spin_button)
{
GtkAdjustment *adjustment;
gdouble value;
@@ -191,15 +191,6 @@ do_spinbutton (GtkWidget *do_widget)
GtkWidget *label;
builder = gtk_builder_new_from_resource ("/spinbutton/spinbutton.ui");
gtk_builder_add_callback_symbols (builder,
"hex_spin_input", G_CALLBACK (hex_spin_input),
"hex_spin_output", G_CALLBACK (hex_spin_output),
"time_spin_input", G_CALLBACK (time_spin_input),
"time_spin_output", G_CALLBACK (time_spin_output),
"month_spin_input", G_CALLBACK (month_spin_input),
"month_spin_output", G_CALLBACK (month_spin_output),
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));

View File

@@ -83,8 +83,8 @@
<property name="halign">start</property>
<property name="width-chars">4</property>
<property name="adjustment">hex_adjustment</property>
<signal name="input" handler="hex_spin_input"/>
<signal name="output" handler="hex_spin_output"/>
<signal name="input" handler="spinbutton_hex_spin_input"/>
<signal name="output" handler="spinbutton_hex_spin_output"/>
<property name="wrap">1</property>
<layout>
<property name="left-attach">1</property>
@@ -119,8 +119,8 @@
<property name="halign">start</property>
<property name="width-chars">5</property>
<property name="adjustment">time_adjustment</property>
<signal name="input" handler="time_spin_input"/>
<signal name="output" handler="time_spin_output"/>
<signal name="input" handler="spinbutton_time_spin_input"/>
<signal name="output" handler="spinbutton_time_spin_output"/>
<property name="wrap">1</property>
<layout>
<property name="left-attach">1</property>
@@ -154,8 +154,8 @@
<object class="GtkSpinButton" id="month_spin">
<property name="halign">start</property>
<property name="width-chars">9</property>
<signal name="input" handler="month_spin_input"/>
<signal name="output" handler="month_spin_output"/>
<signal name="input" handler="spinbutton_month_spin_input"/>
<signal name="output" handler="spinbutton_month_spin_output"/>
<property name="adjustment">month_adjustment</property>
<property name="wrap">1</property>
<property name="update-policy">if-valid</property>

View File

@@ -18,7 +18,6 @@ do_stack (GtkWidget *do_widget)
GtkBuilder *builder;
builder = gtk_builder_new_from_resource ("/stack/stack.ui");
gtk_builder_connect_signals (builder, NULL);
window = GTK_WIDGET (gtk_builder_get_object (builder, "window1"));
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));

71
demos/gtk-demo/textundo.c Normal file
View File

@@ -0,0 +1,71 @@
/* Text View/Undo and Redo
*
* The GtkTextView supports undo and redo through the use of a
* GtkTextBuffer. You can enable or disable undo support using
* gtk_text_buffer_set_enable_undo().
*
* Use Primary+Z to undo and Primary+Shift+Z or Primary+Y to
* redo previously undone operations.
*/
#include <gtk/gtk.h>
#include <stdlib.h> /* for exit() */
GtkWidget *
do_textundo (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
if (!window)
{
GtkWidget *view;
GtkWidget *sw;
GtkTextBuffer *buffer;
GtkTextIter iter;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
gtk_window_set_default_size (GTK_WINDOW (window),
450, 450);
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed), &window);
gtk_window_set_title (GTK_WINDOW (window), "TextView Undo");
view = gtk_text_view_new ();
gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view), GTK_WRAP_WORD);
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
gtk_text_buffer_set_enable_undo (buffer, TRUE);
/* this text cannot be undone */
gtk_text_buffer_begin_irreversible_action (buffer);
gtk_text_buffer_get_start_iter (buffer, &iter);
gtk_text_buffer_insert (buffer, &iter,
"Type to add more text.\n"
"Use Primary+Z to undo and Primary+Shift+Z to redo a previously undone action.\n"
"\n",
-1);
gtk_text_buffer_end_irreversible_action (buffer);
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
gtk_container_add (GTK_CONTAINER (window), sw);
gtk_container_add (GTK_CONTAINER (sw), view);
}
if (!gtk_widget_get_visible (window))
{
gtk_widget_show (window);
}
else
{
gtk_widget_destroy (window);
window = NULL;
}
return window;
}

View File

@@ -128,24 +128,23 @@ 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.
*/
gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
gtk_text_buffer_begin_irreversible_action (buffer);
gtk_text_buffer_insert (buffer, &iter,
"The text widget can display text with all kinds of nifty attributes. "
"It also supports multiple views of the same buffer; this demo is "
@@ -379,7 +378,8 @@ 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);
gtk_text_buffer_end_irreversible_action (buffer);
g_object_unref (texture);
}

View File

@@ -6,236 +6,235 @@
<object class="GtkHeaderBar" id="header">
<property name="show-title-buttons">1</property>
<child type="end">
<object class="GtkLabel" id="fps">
</object>
<object class="GtkLabel" id="fps"/>
</child>
</object>
</child>
<child>
<object class="GtkGrid" id="grid">
<property name="margin">10</property>
<property name="row-spacing">10</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkToolbar">
<property name="hexpand">1</property>
<property name="show-arrow">0</property>
<style>
<class name="primary-toolbar"/>
</style>
<object class="GtkGrid" id="grid">
<property name="margin">10</property>
<property name="row-spacing">10</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkToggleToolButton">
<property name="homogeneous">1</property>
<property name="label" translatable="yes">Normal</property>
<property name="use-underline">1</property>
<property name="is-important">1</property>
<property name="icon-name">edit-find</property>
</object>
</child>
<child>
<object class="GtkToggleToolButton">
<property name="homogeneous">1</property>
<property name="label" translatable="yes">Active</property>
<property name="use-underline">1</property>
<property name="is-important">1</property>
<property name="icon-name">edit-find</property>
<property name="active">1</property>
</object>
</child>
<child>
<object class="GtkToggleToolButton">
<property name="homogeneous">1</property>
<property name="sensitive">0</property>
<property name="label" translatable="yes">Insensitive</property>
<property name="use-underline">1</property>
<property name="is-important">1</property>
<property name="icon-name">edit-find</property>
</object>
</child>
<child>
<object class="GtkToggleToolButton">
<property name="homogeneous">1</property>
<property name="label" translatable="yes">Raised</property>
<property name="use-underline">1</property>
<property name="is-important">1</property>
<property name="icon-name">edit-find</property>
<style>
<class name="raised"/>
</style>
</object>
</child>
<child>
<object class="GtkToggleToolButton">
<property name="homogeneous">1</property>
<property name="label" translatable="yes">Raised Active</property>
<property name="use-underline">1</property>
<property name="is-important">1</property>
<property name="icon-name">edit-find</property>
<property name="active">1</property>
<style>
<class name="raised"/>
</style>
</object>
</child>
<child>
<object class="GtkToggleToolButton">
<property name="homogeneous">1</property>
<property name="sensitive">0</property>
<property name="label" translatable="yes">Insensitive Active</property>
<property name="use-underline">1</property>
<property name="icon-name">edit-find</property>
<property name="is-important">1</property>
<property name="active">1</property>
</object>
</child>
<child>
<object class="GtkToolItem">
<child>
<object class="GtkEntry" id="entry1">
<property name="can-focus">1</property>
<property name="width-chars">10</property>
<property name="invisible-char">•</property>
<property name="placeholder-text" translatable="yes">Search...</property>
<property name="secondary-icon-name">edit-find-symbolic</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkToolItem">
<child>
<object class="GtkSwitch" id="switch1">
<property name="can-focus">1</property>
<property name="valign">center</property>
<property name="tooltip_text">Switch it</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<property name="valign">center</property>
<property name="halign">center</property>
<style>
<class name="linked"/>
</style>
<child>
<object class="GtkButton">
<property name="label" translatable="yes">Hi, I am a button</property>
<property name="can-focus">1</property>
<property name="receives-default">1</property>
</object>
</child>
<child>
<object class="GtkButton">
<property name="label" translatable="yes">And I&apos;m another button</property>
<property name="can-focus">1</property>
<property name="receives-default">1</property>
</object>
</child>
<child>
<object class="GtkButton">
<property name="label" translatable="yes">This is a button party!</property>
<property name="can-focus">1</property>
<property name="receives-default">1</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkToolbar">
<property name="hexpand">1</property>
<property name="toolbar-style">icons</property>
<style>
<class name="inline-toolbar"/>
</style>
<child>
<object class="GtkToggleToolButton">
<property name="homogeneous">1</property>
<property name="label" translatable="yes">Normal</property>
<property name="use-underline">1</property>
<property name="icon-name">list-add-symbolic</property>
</object>
</child>
<child>
<object class="GtkToggleToolButton">
<property name="homogeneous">1</property>
<property name="label" translatable="yes">Normal</property>
<property name="use-underline">1</property>
<property name="icon-name">list-add-symbolic</property>
</object>
</child>
<child>
<object class="GtkToggleToolButton">
<property name="homogeneous">1</property>
<property name="label" translatable="yes">Active</property>
<property name="use-underline">1</property>
<property name="icon-name">list-remove-symbolic</property>
<property name="active">1</property>
</object>
</child>
<child>
<object class="GtkToggleToolButton">
<property name="homogeneous">1</property>
<property name="label" translatable="yes">Active</property>
<property name="use-underline">1</property>
<property name="icon-name">list-remove-symbolic</property>
<property name="active">1</property>
</object>
</child>
<child>
<object class="GtkToggleToolButton">
<property name="homogeneous">1</property>
<property name="sensitive">0</property>
<property name="label" translatable="yes">Insensitive</property>
<property name="use-underline">1</property>
<property name="icon-name">edit-find-symbolic</property>
</object>
</child>
<child>
<object class="GtkToggleToolButton">
<property name="homogeneous">1</property>
<property name="sensitive">0</property>
<property name="label" translatable="yes">Insensitive Active</property>
<property name="use-underline">1</property>
<property name="icon-name">go-up-symbolic</property>
<property name="active">1</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<property name="spacing">10</property>
<child>
<object class="GtkButton">
<property name="label">Plain</property>
<property name="halign">end</property>
<object class="GtkToolbar">
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<property name="show-arrow">0</property>
<style>
<class name="primary-toolbar"/>
</style>
<child>
<object class="GtkToggleToolButton">
<property name="homogeneous">1</property>
<property name="label" translatable="yes">Normal</property>
<property name="use-underline">1</property>
<property name="is-important">1</property>
<property name="icon-name">edit-find</property>
</object>
</child>
<child>
<object class="GtkToggleToolButton">
<property name="homogeneous">1</property>
<property name="label" translatable="yes">Active</property>
<property name="use-underline">1</property>
<property name="is-important">1</property>
<property name="icon-name">edit-find</property>
<property name="active">1</property>
</object>
</child>
<child>
<object class="GtkToggleToolButton">
<property name="homogeneous">1</property>
<property name="sensitive">0</property>
<property name="label" translatable="yes">Insensitive</property>
<property name="use-underline">1</property>
<property name="is-important">1</property>
<property name="icon-name">edit-find</property>
</object>
</child>
<child>
<object class="GtkToggleToolButton">
<property name="homogeneous">1</property>
<property name="label" translatable="yes">Raised</property>
<property name="use-underline">1</property>
<property name="is-important">1</property>
<property name="icon-name">edit-find</property>
<style>
<class name="raised"/>
</style>
</object>
</child>
<child>
<object class="GtkToggleToolButton">
<property name="homogeneous">1</property>
<property name="label" translatable="yes">Raised Active</property>
<property name="use-underline">1</property>
<property name="is-important">1</property>
<property name="icon-name">edit-find</property>
<property name="active">1</property>
<style>
<class name="raised"/>
</style>
</object>
</child>
<child>
<object class="GtkToggleToolButton">
<property name="homogeneous">1</property>
<property name="sensitive">0</property>
<property name="label" translatable="yes">Insensitive Active</property>
<property name="use-underline">1</property>
<property name="icon-name">edit-find</property>
<property name="is-important">1</property>
<property name="active">1</property>
</object>
</child>
<child>
<object class="GtkToolItem">
<child>
<object class="GtkEntry" id="entry1">
<property name="can-focus">1</property>
<property name="width-chars">10</property>
<property name="invisible-char">•</property>
<property name="placeholder-text" translatable="yes">Search...</property>
<property name="secondary-icon-name">edit-find-symbolic</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkToolItem">
<child>
<object class="GtkSwitch" id="switch1">
<property name="can-focus">1</property>
<property name="valign">center</property>
<property name="tooltip_text">Switch it</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkButton">
<property name="label">Destructive</property>
<object class="GtkBox">
<property name="valign">center</property>
<property name="halign">center</property>
<style>
<class name="destructive-action"/>
<class name="linked"/>
</style>
<child>
<object class="GtkButton">
<property name="label" translatable="yes">Hi, I am a button</property>
<property name="can-focus">1</property>
<property name="receives-default">1</property>
</object>
</child>
<child>
<object class="GtkButton">
<property name="label" translatable="yes">And I&apos;m another button</property>
<property name="can-focus">1</property>
<property name="receives-default">1</property>
</object>
</child>
<child>
<object class="GtkButton">
<property name="label" translatable="yes">This is a button party!</property>
<property name="can-focus">1</property>
<property name="receives-default">1</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkButton">
<property name="label">Suggested</property>
<object class="GtkToolbar">
<property name="hexpand">1</property>
<property name="toolbar-style">icons</property>
<style>
<class name="suggested-action"/>
<class name="inline-toolbar"/>
</style>
<child>
<object class="GtkToggleToolButton">
<property name="homogeneous">1</property>
<property name="label" translatable="yes">Normal</property>
<property name="use-underline">1</property>
<property name="icon-name">list-add-symbolic</property>
</object>
</child>
<child>
<object class="GtkToggleToolButton">
<property name="homogeneous">1</property>
<property name="label" translatable="yes">Normal</property>
<property name="use-underline">1</property>
<property name="icon-name">list-add-symbolic</property>
</object>
</child>
<child>
<object class="GtkToggleToolButton">
<property name="homogeneous">1</property>
<property name="label" translatable="yes">Active</property>
<property name="use-underline">1</property>
<property name="icon-name">list-remove-symbolic</property>
<property name="active">1</property>
</object>
</child>
<child>
<object class="GtkToggleToolButton">
<property name="homogeneous">1</property>
<property name="label" translatable="yes">Active</property>
<property name="use-underline">1</property>
<property name="icon-name">list-remove-symbolic</property>
<property name="active">1</property>
</object>
</child>
<child>
<object class="GtkToggleToolButton">
<property name="homogeneous">1</property>
<property name="sensitive">0</property>
<property name="label" translatable="yes">Insensitive</property>
<property name="use-underline">1</property>
<property name="icon-name">edit-find-symbolic</property>
</object>
</child>
<child>
<object class="GtkToggleToolButton">
<property name="homogeneous">1</property>
<property name="sensitive">0</property>
<property name="label" translatable="yes">Insensitive Active</property>
<property name="use-underline">1</property>
<property name="icon-name">go-up-symbolic</property>
<property name="active">1</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<property name="spacing">10</property>
<child>
<object class="GtkButton">
<property name="label">Plain</property>
<property name="halign">end</property>
<property name="hexpand">1</property>
<property name="vexpand">1</property>
</object>
</child>
<child>
<object class="GtkButton">
<property name="label">Destructive</property>
<style>
<class name="destructive-action"/>
</style>
</object>
</child>
<child>
<object class="GtkButton">
<property name="label">Suggested</property>
<style>
<class name="suggested-action"/>
</style>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>

View File

@@ -2,6 +2,7 @@
<interface>
<object class="GtkGrid" id="grid">
<property name="row-spacing">10</property>
<property name="margin">10</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkToolbar">
@@ -92,6 +93,7 @@
<child>
<object class="GtkSwitch" id="switch1">
<property name="can-focus">1</property>
<property name="valign">center</property>
<property name="tooltip_text">Switch it</property>
</object>
</child>

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

@@ -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

@@ -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);
}
@@ -1649,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);
@@ -1660,6 +1663,7 @@ static void
activate (GApplication *app)
{
GtkBuilder *builder;
GtkBuilderScope *scope;
GtkWindow *window;
GtkWidget *widget;
GtkWidget *widget2;
@@ -1712,21 +1716,25 @@ activate (GApplication *app)
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
g_object_unref (provider);
builder = gtk_builder_new_from_resource ("/org/gtk/WidgetFactory4/widget-factory.ui");
gtk_builder_add_callback_symbol (builder, "on_entry_icon_release", (GCallback)on_entry_icon_release);
gtk_builder_add_callback_symbol (builder, "on_scale_button_value_changed", (GCallback)on_scale_button_value_changed);
gtk_builder_add_callback_symbol (builder, "on_scale_button_query_tooltip", (GCallback)on_scale_button_query_tooltip);
gtk_builder_add_callback_symbol (builder, "on_record_button_toggled", (GCallback)on_record_button_toggled);
gtk_builder_add_callback_symbol (builder, "on_page_combo_changed", (GCallback)on_page_combo_changed);
gtk_builder_add_callback_symbol (builder, "on_range_from_changed", (GCallback)on_range_from_changed);
gtk_builder_add_callback_symbol (builder, "on_range_to_changed", (GCallback)on_range_to_changed);
gtk_builder_add_callback_symbol (builder, "tab_close_cb", (GCallback)tab_close_cb);
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, "osd_frame_pressed", (GCallback)osd_frame_pressed);
gtk_builder_connect_signals (builder, NULL);
builder = gtk_builder_new ();
scope = gtk_builder_cscope_new ();
gtk_builder_cscope_add_callback_symbols (GTK_BUILDER_CSCOPE (scope),
"on_entry_icon_release", (GCallback)on_entry_icon_release,
"on_scale_button_value_changed", (GCallback)on_scale_button_value_changed,
"on_scale_button_query_tooltip", (GCallback)on_scale_button_query_tooltip,
"on_record_button_toggled", (GCallback)on_record_button_toggled,
"on_page_combo_changed", (GCallback)on_page_combo_changed,
"on_range_from_changed", (GCallback)on_range_from_changed,
"on_range_to_changed", (GCallback)on_range_to_changed,
"tab_close_cb", (GCallback)tab_close_cb,
"increase_icon_size", (GCallback)increase_icon_size,
"decrease_icon_size", (GCallback)decrease_icon_size,
"reset_icon_size", (GCallback)reset_icon_size,
"osd_frame_pressed", (GCallback)osd_frame_pressed,
NULL);
gtk_builder_set_scope (builder, scope);
g_object_unref (scope);
gtk_builder_add_from_resource (builder, "/org/gtk/WidgetFactory4/widget-factory.ui", NULL);
window = (GtkWindow *)gtk_builder_get_object (builder, "window");
gtk_application_add_window (GTK_APPLICATION (app), window);

View File

@@ -598,10 +598,6 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
<property name="label" translatable="yes">checkbutton</property>
<property name="can-focus">1</property>
<property name="active">1</property>
<layout>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</layout>
</object>
</child>
<child>
@@ -666,8 +662,8 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
<property name="can-focus">1</property>
<property name="active">1</property>
<layout>
<property name="left-attach">0</property>
<property name="left-attach">1</property>
<property name="top-attach">0</property>
</layout>
</object>
</child>
@@ -740,7 +736,6 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
<property name="active">1</property>
<layout>
<property name="left-attach">2</property>
<property name="top-attach">0</property>
</layout>
</object>
</child>
@@ -971,11 +966,11 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
<property name="adjustment">adjustment3</property>
<property name="restrict-to-fill-level">0</property>
<marks>
<mark value="0" position="bottom"/>
<mark value="1" position="bottom"/>
<mark value="2" position="bottom"/>
<mark value="3" position="bottom"/>
<mark value="4" position="bottom"/>
<mark value="0" position="bottom"></mark>
<mark value="1" position="bottom"></mark>
<mark value="2" position="bottom"></mark>
<mark value="3" position="bottom"></mark>
<mark value="4" position="bottom"></mark>
</marks>
</object>
</child>
@@ -1505,10 +1500,6 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
<property name="valign">center</property>
<property name="value">.5</property>
<property name="halign">center</property>
<layout>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</layout>
</object>
</child>
<child>
@@ -1524,7 +1515,6 @@ microphone-sensitivity-medium-symbolic</property>
<signal name="query-tooltip" handler="on_scale_button_query_tooltip" swapped="no"/>
<signal name="value-changed" handler="on_scale_button_value_changed" swapped="no"/>
<layout>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</layout>
</object>
@@ -1575,7 +1565,7 @@ microphone-sensitivity-medium-symbolic</property>
<property name="icon-name">org.gtk.WidgetFactory4</property>
<property name="pixel-size">256</property>
<style>
<class name="icon-dropshadow" />
<class name="icon-dropshadow"/>
</style>
</object>
</property>
@@ -1726,15 +1716,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>
@@ -1909,11 +1895,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>
@@ -1957,9 +1943,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>
@@ -2118,7 +2111,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">
@@ -2129,9 +2122,11 @@ microphone-sensitivity-medium-symbolic</property>
</child>
</object>
</child>
<child>
<object class="GtkSeparator"/>
</child>
<child>
<object class="GtkScrolledWindow">
<property name="shadow-type">in</property>
<property name="vexpand">1</property>
<child>
<object class="MyTextView" id="text3">
@@ -2145,6 +2140,9 @@ microphone-sensitivity-medium-symbolic</property>
</child>
</object>
</child>
<child>
<object class="GtkSeparator"/>
</child>
<child>
<object class="GtkStatusbar" id="statusbar"/>
</child>
@@ -2435,11 +2433,9 @@ microphone-sensitivity-medium-symbolic</property>
<property name="spacing">10</property>
<child>
<object class="GtkBox">
<property name="halign">fill</property>
<property name="spacing">6</property>
<child>
<object class="GtkBox" id="lockbox">
<property name="halign">fill</property>
<property name="hexpand">1</property>
<property name="spacing">6</property>
<child>
@@ -2516,9 +2512,6 @@ microphone-sensitivity-medium-symbolic</property>
<object class="GtkMenuButton">
<property name="icon-name">view-more-symbolic</property>
<property name="popover">new_style_menu</property>
<!--
<property name="menu-model">new_style_menu_model</property>
-->
</object>
</child>
</object>
@@ -3353,10 +3346,6 @@ bad things might happen.</property>
<accessibility>
<relation type="label-for" target="open_popover_entry"/>
</accessibility>
<layout>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</layout>
</object>
</child>
<child>
@@ -3368,7 +3357,6 @@ bad things might happen.</property>
<relation type="label-for" target="open_popover_textview"/>
</accessibility>
<layout>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</layout>
</object>
@@ -3403,7 +3391,6 @@ bad things might happen.</property>
</accessibility>
<layout>
<property name="left-attach">1</property>
<property name="top-attach">0</property>
<property name="column-span">2</property>
</layout>
</object>
@@ -3442,7 +3429,6 @@ bad things might happen.</property>
</child>
<child>
<object class="GtkButton" id="open_popover_button">
<property name="halign">fill</property>
<property name="label">_Open</property>
<property name="use-underline">1</property>
<property name="sensitive">0</property>
@@ -3491,7 +3477,7 @@ bad things might happen.</property>
<property name="autohide">0</property>
<child>
<object class="GtkLabel">
<property name="label">You're in too deep!</property>
<property name="label">You&apos;re in too deep!</property>
<accessibility>
<role type="static"/>
</accessibility>
@@ -3502,7 +3488,6 @@ bad things might happen.</property>
<property name="autohide">0</property>
<child>
<object class="GtkBox">
<property name="orientation">horizontal</property>
<child>
<object class="GtkLabel">
<property name="label">Hidden gems:</property>
@@ -3522,222 +3507,246 @@ bad things might happen.</property>
</object>
</child>
</object>
<object class="GtkPopoverMenu" id="new_style_menu">
<object class="GtkPopover" id="new_style_menu">
<child>
<object class="GtkBox">
<property name="name">main</property>
<property name="orientation">vertical</property>
<object class="GtkStack">
<child>
<object class="GtkBox">
<property name="halign">fill</property>
<style>
<class name="circular-buttons"/>
</style>
<child>
<object class="GtkModelButton">
<property name="icon"><object class="GThemedIcon"><property name="name">printer-symbolic</property></object></property>
<property name="iconic">1</property>
<property name="action-name">app.print</property>
<property name="hexpand">1</property>
<property name="halign">center</property>
<style>
<class name="circular"/>
</style>
<object class="GtkStackPage">
<property name="name">main</property>
<property name="child">
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="GtkBox">
<style>
<class name="circular-buttons"/>
</style>
<child>
<object class="GtkModelButton">
<property name="icon">
<object class="GThemedIcon">
<property name="name">printer-symbolic</property>
</object>
</property>
<property name="iconic">1</property>
<property name="action-name">app.print</property>
<property name="hexpand">1</property>
<property name="halign">center</property>
<style>
<class name="circular"/>
</style>
</object>
</child>
<child>
<object class="GtkModelButton">
<property name="icon">
<object class="GThemedIcon">
<property name="name">emblem-shared-symbolic</property>
</object>
</property>
<property name="iconic">1</property>
<property name="action-name">app.share</property>
<property name="hexpand">1</property>
<property name="halign">center</property>
<style>
<class name="circular"/>
</style>
</object>
</child>
</object>
</child>
<child>
<object class="GtkSeparator"/>
</child>
<child>
<object class="GtkModelButton">
<property name="text">Open in New Window</property>
<property name="action-name">app.open-in</property>
<property name="indicator-size-group">main-indicators</property>
</object>
</child>
<child>
<object class="GtkSeparator"/>
</child>
<child>
<object class="GtkBox">
<style>
<class name="inline-buttons"/>
</style>
<child>
<object class="GtkLabel" id="cut_copy_paste_filler"/>
</child>
<child>
<object class="GtkLabel">
<property name="label">Edit</property>
<property name="xalign">0</property>
<property name="hexpand">1</property>
</object>
</child>
<child>
<object class="GtkModelButton">
<property name="icon">
<object class="GThemedIcon">
<property name="name">edit-cut-symbolic</property>
</object>
</property>
<property name="iconic">1</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>
</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>
</object>
</child>
</object>
</child>
<child>
<object class="GtkSeparator"/>
</child>
<child>
<object class="GtkModelButton">
<property name="text">Pin</property>
<property name="action-name">app.pin</property>
<property name="indicator-size-group">main-indicators</property>
</object>
</child>
<child>
<object class="GtkModelButton">
<property name="text">Select Labels…</property>
<property name="action-name">app.labels</property>
<property name="indicator-size-group">main-indicators</property>
</object>
</child>
<child>
<object class="GtkModelButton">
<property name="text">Share…</property>
<property name="action-name">app.share</property>
<property name="indicator-size-group">main-indicators</property>
</object>
</child>
<child>
<object class="GtkSeparator"/>
</child>
<child>
<object class="GtkModelButton">
<property name="text">Basement</property>
<property name="menu-name">basement</property>
<property name="indicator-size-group">main-indicators</property>
</object>
</child>
<child>
<object class="GtkSeparator"/>
</child>
<child>
<object class="GtkModelButton">
<property name="text">Large</property>
<property name="action-name">app.size</property>
<property name="action-target">&apos;large&apos;</property>
<property name="indicator-size-group">main-indicators</property>
</object>
</child>
<child>
<object class="GtkModelButton">
<property name="text">Medium</property>
<property name="action-name">app.size</property>
<property name="action-target">&apos;medium&apos;</property>
<property name="indicator-size-group">main-indicators</property>
</object>
</child>
<child>
<object class="GtkModelButton">
<property name="text">Small</property>
<property name="action-name">app.size</property>
<property name="action-target">&apos;small&apos;</property>
<property name="indicator-size-group">main-indicators</property>
</object>
</child>
<child>
<object class="GtkSeparator"/>
</child>
<child>
<object class="GtkModelButton">
<property name="text">Move to Trash</property>
<property name="action-name">win.delete</property>
<property name="indicator-size-group">main-indicators</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkModelButton">
<property name="icon"><object class="GThemedIcon"><property name="name">emblem-shared-symbolic</property></object></property>
<property name="iconic">1</property>
<property name="action-name">app.share</property>
<property name="hexpand">1</property>
<property name="halign">center</property>
<style>
<class name="circular"/>
</style>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">basement</property>
<property name="child">
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="GtkModelButton">
<property name="text">Basement</property>
<property name="role">title</property>
<property name="menu-name">main</property>
</object>
</child>
<child>
<object class="GtkSeparator"/>
</child>
<child>
<object class="GtkModelButton">
<property name="text">Berk</property>
<property name="action-name">app.berk</property>
<property name="indicator-size-group">basement-indicators</property>
</object>
</child>
<child>
<object class="GtkModelButton">
<property name="text">Broni</property>
<property name="action-name">app.broni</property>
<property name="indicator-size-group">basement-indicators</property>
</object>
</child>
<child>
<object class="GtkModelButton">
<property name="text">Drutt</property>
<property name="action-name">app.drutt</property>
<property name="indicator-size-group">basement-indicators</property>
</object>
</child>
<child>
<object class="GtkModelButton">
<property name="text">The Thing Upstairs</property>
<property name="action-name">app.upstairs</property>
<property name="indicator-size-group">basement-indicators</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkSeparator"/>
</child>
<child>
<object class="GtkModelButton">
<property name="text">Open in New Window</property>
<property name="action-name">app.open-in</property>
<property name="indicator-size-group">main-indicators</property>
</object>
</child>
<child>
<object class="GtkSeparator"/>
</child>
<child>
<object class="GtkBox">
<style>
<class name="inline-buttons"/>
</style>
<child>
<object class="GtkLabel" id="cut_copy_paste_filler">
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Edit</property>
<property name="xalign">0</property>
<property name="hexpand">1</property>
</object>
</child>
<child>
<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>
</child>
<child>
<object class="GtkSeparator"/>
</child>
<child>
<object class="GtkModelButton">
<property name="text">Pin</property>
<property name="action-name">app.pin</property>
<property name="indicator-size-group">main-indicators</property>
</object>
</child>
<child>
<object class="GtkModelButton">
<property name="text">Select Labels…</property>
<property name="action-name">app.labels</property>
<property name="indicator-size-group">main-indicators</property>
</object>
</child>
<child>
<object class="GtkModelButton">
<property name="text">Share…</property>
<property name="action-name">app.share</property>
<property name="indicator-size-group">main-indicators</property>
</object>
</child>
<child>
<object class="GtkSeparator"/>
</child>
<child>
<object class="GtkModelButton">
<property name="text">Basement</property>
<property name="menu-name">basement</property>
<property name="indicator-size-group">main-indicators</property>
</object>
</child>
<child>
<object class="GtkSeparator"/>
</child>
<child>
<object class="GtkModelButton">
<property name="text">Large</property>
<property name="action-name">app.size</property>
<property name="action-target">'large'</property>
<property name="indicator-size-group">main-indicators</property>
</object>
</child>
<child>
<object class="GtkModelButton">
<property name="text">Medium</property>
<property name="action-name">app.size</property>
<property name="action-target">'medium'</property>
<property name="indicator-size-group">main-indicators</property>
</object>
</child>
<child>
<object class="GtkModelButton">
<property name="text">Small</property>
<property name="action-name">app.size</property>
<property name="action-target">'small'</property>
<property name="indicator-size-group">main-indicators</property>
</object>
</child>
<child>
<object class="GtkSeparator"/>
</child>
<child>
<object class="GtkModelButton">
<property name="text">Move to Trash</property>
<property name="action-name">win.delete</property>
<property name="indicator-size-group">main-indicators</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<property name="name">basement</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkModelButton">
<property name="text">Basement</property>
<property name="role">title</property>
<property name="menu-name">main</property>
</object>
</child>
<child>
<object class="GtkSeparator"/>
</child>
<child>
<object class="GtkModelButton">
<property name="text">Berk</property>
<property name="action-name">app.berk</property>
<property name="indicator-size-group">basement-indicators</property>
</object>
</child>
<child>
<object class="GtkModelButton">
<property name="text">Broni</property>
<property name="action-name">app.broni</property>
<property name="indicator-size-group">basement-indicators</property>
</object>
</child>
<child>
<object class="GtkModelButton">
<property name="text">Drutt</property>
<property name="action-name">app.drutt</property>
<property name="indicator-size-group">basement-indicators</property>
</object>
</child>
<child>
<object class="GtkModelButton">
<property name="text">The Thing Upstairs</property>
<property name="action-name">app.upstairs</property>
<property name="indicator-size-group">basement-indicators</property>
</property>
</object>
</child>
</object>
</child>
</object>
<object class="GtkSizeGroup" id="main-indicators">
<property name="mode">horizontal</property>
<widgets>
<widget name="cut_copy_paste_filler"/>
</widgets>
</object>
<object class="GtkSizeGroup" id="basement-indicators">
<property name="mode">horizontal</property>
</object>
<object class="GtkSizeGroup" id="basement-indicators"/>
<menu id="new_style_menu_model">
<section>
<attribute name="display-hint">circular-buttons</attribute>
@@ -3827,10 +3836,10 @@ bad things might happen.</property>
</item>
</section>
<section>
<item>
<attribute name="label" translatable="yes">Move to Trash</attribute>
<attribute name="action">win.delete</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Move to Trash</attribute>
<attribute name="action">win.delete</attribute>
</item>
</section>
</menu>
<menu id="new_style_context_menu_model">
@@ -3944,7 +3953,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>
@@ -3968,6 +3977,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>
@@ -4018,14 +4030,13 @@ bad things might happen.</property>
<attribute name="action">win.background</attribute>
</item>
</section>
</submenu>
<submenu>
<attribute name="label" translatable="yes">_Help</attribute>
<item>
<attribute name="label" translatable="yes">About</attribute>
<attribute name="action">app.about</attribute>
</item>
<item>
<attribute name="label" translatable="yes">About</attribute>
<attribute name="action">app.about</attribute>
</item>
</submenu>
</menu>
</interface>

View File

@@ -192,8 +192,8 @@ gdk_surface_is_destroyed
gdk_surface_is_visible
gdk_surface_is_viewable
gdk_surface_get_state
gdk_surface_iconify
gdk_surface_deiconify
gdk_surface_minimize
gdk_surface_unminimize
gdk_surface_stick
gdk_surface_unstick
gdk_surface_maximize
@@ -789,8 +789,6 @@ gdk_drop_get_type
</SECTION>
<SECTION>
<INCLUDE>gdk/gdkx.h</INCLUDE>
<TITLE>X Window System Interaction</TITLE>
<FILE>x_interaction</FILE>
GDK_SURFACE_XID
GDK_DISPLAY_XDISPLAY
@@ -941,8 +939,6 @@ gdk_surface_impl_x11_get_type
</SECTION>
<SECTION>
<INCLUDE>gdk/gdkwayland.h</INCLUDE>
<TITLE>Wayland Interaction</TITLE>
<FILE>wayland_interaction</FILE>
gdk_wayland_seat_get_wl_seat
gdk_wayland_device_get_wl_keyboard

View File

@@ -76,10 +76,10 @@ How to compile GTK itself
</para>
<para>
Several environment variables are useful to pass to set before
running configure. <envar>CPPFLAGS</envar> contains options to
pass to the C compiler, and is used to tell the compiler where
to look for include files. The <envar>LDFLAGS</envar> variable
is used in a similar fashion for the linker. Finally the
running <application>meson</application>. <envar>CPPFLAGS</envar>
contains options to pass to the C compiler, and is used to tell
the compiler where to look for include files. The <envar>LDFLAGS</envar>
variable is used in a similar fashion for the linker. Finally the
<envar>PKG_CONFIG_PATH</envar> environment variable contains
a search path that <command>pkg-config</command> (see below)
uses when looking for files describing how to compile
@@ -106,6 +106,61 @@ How to compile GTK itself
export LD_LIBRARY_PATH PATH
</programlisting>
</refsect1>
<refsect1 id="build-types">
<title>Build types</title>
<para>Meson has different build types, exposed by the <literal>buildtype</literal>
configuration option. GTK enables and disables functionality depending on
the build type used when calling <application>meson</application> to
configure the build.</para>
<formalpara>
<title><systemitem>debug</systemitem> and <systemitem>debugoptimized</systemitem></title>
<para>
GTK will enable debugging code paths in both the
<literal>debug</literal> and <literal>debugoptimized</literal>
build types. Builds with <literal>buildtype</literal> set
to <literal>debug</literal> will additionally enable
consistency checks on the internal state of the toolkit.
</para>
<para>
It is recommended to use the <literal>debug</literal> or
<literal>debugoptimized</literal> build types when developing
GTK itself. Additionally, <literal>debug</literal> builds of
GTK are recommended for profiling and debugging GTK applications,
as they include additional validation of the internal state.
</para>
<para>
The <literal>debugoptimized</literal> build type is the
default for GTK if no build type is specified when calling
<application>meson</application>
</para>
</formalpara>
<formalpara>
<title><systemitem>release</systemitem></title>
<para>
The <literal>release</literal> build type will disable
debugging code paths and additional run time safeties, like
checked casts for object instances.
</para>
</formalpara>
<para>
The <literal>plain</literal> build type provided by Meson
should only be used when packaging GTK, and it's expected
that packagers will provide their own compiler flags when
building GTK. See the previous section for the list of
environment variables to be used to define compiler and
linker flags.
</para>
</refsect1>
<refsect1 id="dependencies">
<title>Dependencies</title>
<para>
@@ -283,184 +338,181 @@ How to compile GTK itself
See <xref linkend="gtk-resources"/> for more information.
</para>
</refsect1>
<refsect1 id="extra-configuration-options">
<title>Extra Configuration Options</title>
<refsect1 id="extra-configuration-options">
<title>Extra Configuration Options</title>
<para>
In addition to the normal options provided by Meson, GTK defines
various arguments that modify what should be built.
<cmdsynopsis>
<command>meson</command>
<sbr/>
<group>
<arg choice="plain">-Dx11-backend=true</arg>
<arg choice="plain">-Dx11-backend=false</arg>
</group>
<sbr/>
<group>
<arg choice="plain">-Dwayland-backend=true</arg>
<arg choice="plain">-Dwayland-backend=false</arg>
</group>
<sbr/>
<group>
<arg choice="plain">-Dbroadway-backend=true</arg>
<arg choice="plain">-Dbroadway-backend=false</arg>
</group>
<sbr/>
<group>
<arg choice="plain">-Dwin32-backend=true</arg>
<arg choice="plain">-Dwin32-backend=false</arg>
</group>
<sbr/>
<group>
<arg choice="plain">-Dquartz-backend=true</arg>
<arg choice="plain">-Dquartz-backend=false</arg>
</group>
<sbr/>
<group>
<arg choice="plain">-Dmedia=gstreamer</arg>
<arg choice="plain">-Dmedia=ffmpeg</arg>
<arg choice="plain">-Dmedia=all</arg>
<arg choice="plain">-Dmedia=none</arg>
</group>
<sbr/>
<group>
<arg choice="plain">-Dvulkan=yes</arg>
<arg choice="plain">-Dvulkan=no</arg>
<arg choice="plain">-Dvulkan=auto</arg>
</group>
<sbr/>
<group>
<arg choice="plain">-Dxinerama=yes</arg>
<arg choice="plain">-Dxinerama=no</arg>
<arg choice="plain">-Dxinerama=auto</arg>
</group>
<sbr/>
<group>
<arg choice="plain">-Dcloudproviders=true</arg>
<arg choice="plain">-Dcloudproviders=false</arg>
</group>
<sbr/>
<group>
<arg choice="plain">-Dprint-backends=all</arg>
<arg choice="plain">-Dprint-backends=none</arg>
<arg choice="plain">-Dprint-backends=cups,lpr,...</arg>
</group>
<sbr/>
<group>
<arg choice="plain">-Dcolord=yes</arg>
<arg choice="plain">-Dcolord=no</arg>
<arg choice="plain">-Dcolord=auto</arg>
</group>
<sbr/>
<group>
<arg choice="plain">-Dgtk_doc=true</arg>
<arg choice="plain">-Dgtk_doc=false</arg>
</group>
<sbr/>
<group>
<arg choice="plain">-Dman-pages=true</arg>
<arg choice="plain">-Dman-pages=false</arg>
</group>
<sbr/>
<group>
<arg choice="plain">-Dintrospection=true</arg>
<arg choice="plain">-Dintrospection=false</arg>
</group>
</cmdsynopsis>
</para>
<formalpara>
<title><systemitem>xinerama</systemitem></title>
<para>
In addition to the normal options provided by Meson, GTK defines
various arguments that modify what should be built.
<cmdsynopsis>
<command>meson</command>
<sbr/>
<group>
<arg choice="plain">-Dx11-backend=true</arg>
<arg choice="plain">-Dx11-backend=false</arg>
</group>
<sbr/>
<group>
<arg choice="plain">-Dwayland-backend=true</arg>
<arg choice="plain">-Dwayland-backend=false</arg>
</group>
<sbr/>
<group>
<arg choice="plain">-Dbroadway-backend=true</arg>
<arg choice="plain">-Dbroadway-backend=false</arg>
</group>
<sbr/>
<group>
<arg choice="plain">-Dwin32-backend=true</arg>
<arg choice="plain">-Dwin32-backend=false</arg>
</group>
<sbr/>
<group>
<arg choice="plain">-Dquartz-backend=true</arg>
<arg choice="plain">-Dquartz-backend=false</arg>
</group>
<sbr/>
<group>
<arg choice="plain">-Dmedia=gstreamer</arg>
<arg choice="plain">-Dmedia=ffmpeg</arg>
<arg choice="plain">-Dmedia=all</arg>
<arg choice="plain">-Dmedia=none</arg>
</group>
<sbr/>
<group>
<arg choice="plain">-Dvulkan=yes</arg>
<arg choice="plain">-Dvulkan=no</arg>
<arg choice="plain">-Dvulkan=auto</arg>
</group>
<sbr/>
<group>
<arg choice="plain">-Dxinerama=yes</arg>
<arg choice="plain">-Dxinerama=no</arg>
<arg choice="plain">-Dxinerama=auto</arg>
</group>
<sbr/>
<group>
<arg choice="plain">-Dcloudproviders=true</arg>
<arg choice="plain">-Dcloudproviders=false</arg>
</group>
<sbr/>
<group>
<arg choice="plain">-Dprint-backends=all</arg>
<arg choice="plain">-Dprint-backends=none</arg>
<arg choice="plain">-Dprint-backends=cups,lpr,...</arg>
</group>
<sbr/>
<group>
<arg choice="plain">-Dcolord=yes</arg>
<arg choice="plain">-Dcolord=no</arg>
<arg choice="plain">-Dcolord=auto</arg>
</group>
<sbr/>
<group>
<arg choice="plain">-Dgtk_doc=true</arg>
<arg choice="plain">-Dgtk_doc=false</arg>
</group>
<sbr/>
<group>
<arg choice="plain">-Dman-pages=true</arg>
<arg choice="plain">-Dman-pages=false</arg>
</group>
<sbr/>
<group>
<arg choice="plain">-Dintrospection=true</arg>
<arg choice="plain">-Dintrospection=false</arg>
</group>
</cmdsynopsis>
By default GTK will try to link against the Xinerama libraries
if they are found. This options can be used to explicitly control
whether Xinerama should be used.
</para>
</formalpara>
<formalpara>
<title><systemitem>xinerama</systemitem></title>
<formalpara>
<title><systemitem>gtk_doc</systemitem> and
<systemitem>man-pages</systemitem></title>
<para>
By default GTK will try to link against the Xinerama libraries
if they are found. This options can be used to explicitly control
whether Xinerama should be used.
</para>
</formalpara>
<para>
The <application>gtk-doc</application> package is
used to generate the reference documentation included
with GTK. By default support for <application>gtk-doc</application>
is disabled because it requires various extra dependencies
to be installed. If you have
<application>gtk-doc</application> installed and
are modifying GTK, you may want to enable
<application>gtk-doc</application> support by passing
in <systemitem>gtk_doc</systemitem>.
</para>
<para>
Additionally, some tools provided by GTK have their own
manual pages generated using a similar set of dependencies;
if you have <application>xsltproc</application> then you
can generate manual pages by passing <systemitem>man-pages</systemitem>
when configuring the build.
</para>
</formalpara>
<formalpara>
<title><systemitem>gtk_doc</systemitem> and
<systemitem>man-pages</systemitem></title>
<formalpara>
<title><systemitem>print-backends</systemitem></title>
<para>
The <application>gtk-doc</application> package is
used to generate the reference documentation included
with GTK. By default support for <application>gtk-doc</application>
is disabled because it requires various extra dependencies
to be installed. If you have
<application>gtk-doc</application> installed and
are modifying GTK, you may want to enable
<application>gtk-doc</application> support by passing
in <systemitem>gtk_doc</systemitem>.
</para>
<para>
Additionally, some tools provided by GTK have their own
manual pages generated using a similar set of dependencies;
if you have <application>xsltproc</application> then you
can generate manual pages by passing <systemitem>man-pages</systemitem>
when configuring the build.
</para>
</formalpara>
<para>
By default, GTK will try to build various print backends if
their dependencies are found. This option can be used to
explicitly control which print backends should be built.
</para>
</formalpara>
<formalpara>
<title><systemitem>print-backends</systemitem></title>
<formalpara>
<title><systemitem>x11-backend</systemitem>,
<systemitem>win32-backend</systemitem>,
<systemitem>quartz-backend</systemitem>,
<systemitem>broadway-backend</systemitem> and
<systemitem>wayland-backend</systemitem></title>
<para>
By default, GTK will try to build various print backends if
their dependencies are found. This option can be used to
explicitly control which print backends should be built.
</para>
</formalpara>
<para>
Enable specific backends for GDK. If none of these options
are given, the Wayland backend will be enabled by default,
if the platform is Linux; the X11 backend will also be enabled
by default, unless the platform is Windows, in which case the
default is win32, or the platform is macOS, in which case the
default is quartz. If any backend is explicitly enabled or disabled,
no other platform will be enabled automatically.
</para>
</formalpara>
<formalpara>
<title><systemitem>x11-backend</systemitem>,
<systemitem>win32-backend</systemitem>,
<systemitem>quartz-backend</systemitem>,
<systemitem>broadway-backend</systemitem> and
<systemitem>wayland-backend</systemitem></title>
<formalpara>
<title><systemitem>introspection</systemitem></title>
<para>
Enable specific backends for GDK. If none of these options
are given, the Wayland backend will be enabled by default,
if the platform is Linux; the X11 backend will also be enabled
by default, unless the platform is Windows, in which case the
default is win32, or the platform is macOS, in which case the
default is quartz. If any backend is explicitly enabled or disabled,
no other platform will be enabled automatically.
</para>
</formalpara>
<para>
Allows to disable building introspection support. This is option
is mainly useful for shortening turnaround times on developer
systems. Installed builds of GTK should always have introspection
support.
</para>
</formalpara>
<formalpara>
<title><systemitem>introspection</systemitem></title>
<formalpara>
<title><systemitem>build-tests</systemitem>,
<systemitem>install-tests</systemitem>,
<systemitem>demos</systemitem></title>
<para>
Allows to disable building introspection support. This is option
is mainly useful for shortening turnaround times on developer
systems. Installed builds of GTK should always have introspection
support.
</para>
</formalpara>
<para>
By default, GTK will build quite a few tests and demos.
While these are useful on a developer system, they are not
needed when GTK is built e.g. for a flatpak runtime. These
options allow to disable building tests and demos.
</para>
</formalpara>
<formalpara>
<title><systemitem>build-tests</systemitem>,
<systemitem>install-tests</systemitem>,
<systemitem>demos</systemitem></title>
<para>
By default, GTK will build quite a few tests and demos.
While these are useful on a developer system, they are not
needed when GTK is built e.g. for a flatpak runtime. These
options allow to disable building tests and demos.
</para>
</formalpara>
</refsect1>
</refsect1>
</refentry>
<!-- Local Variables: -->
<!-- sgml-parent-document: ("gtk-docs.sgml" "chapter" "refentry") -->
<!-- End: -->

View File

@@ -224,10 +224,3 @@
</refsect1>
</refentry>
<!--
Local variables:
mode: xml
sgml-parent-document: ("gtk-docs.sgml" "book" "part" "refentry")
End:
-->

View File

@@ -364,10 +364,3 @@
</glossdef>
</glossentry>
</glossary>
<!--
Local variables:
mode: sgml
sgml-parent-document: ("gtk-docs.sgml" "book" "glossary")
End:
-->

View File

@@ -22,8 +22,8 @@
<title>GTK Overview</title>
<xi:include href="overview.xml"/>
<xi:include href="xml/getting_started.xml"/>
<xi:include href="resources.sgml" />
<xi:include href="xml/question_index.sgml" />
<xi:include href="resources.xml" />
<xi:include href="xml/question_index.xml" />
<xi:include href="xml/drawing-model.xml" />
<xi:include href="xml/input-handling.xml" />
<xi:include href="xml/actions.xml" />
@@ -44,14 +44,51 @@
<chapter id="Lists">
<title>GListModel support</title>
<xi:include href="xml/gtkexpression.xml" />
<xi:include href="xml/gtkfilterlistmodel.xml" />
<section>
<xi:include href="xml/gtkfilter.xml" />
<xi:include href="xml/gtkcustomfilter.xml" />
<xi:include href="xml/gtkstringfilter.xml" />
<xi:include href="xml/gtkmultifilter.xml" />
</section>
<xi:include href="xml/gtkflattenlistmodel.xml" />
<xi:include href="xml/gtkmaplistmodel.xml" />
<xi:include href="xml/gtkslicelistmodel.xml" />
<xi:include href="xml/gtksortlistmodel.xml" />
<xi:include href="xml/gtktreelistmodel.xml" />
<section>
<xi:include href="xml/gtksorter.xml" />
<xi:include href="xml/gtkcustomsorter.xml" />
<xi:include href="xml/gtkstringsorter.xml" />
<xi:include href="xml/gtknumericsorter.xml" />
<xi:include href="xml/gtkmultisorter.xml" />
</section>
<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="ListContainers">
<title>List-based Widgets</title>
<xi:include href="xml/gtklistitem.xml" />
<xi:include href="xml/gtklistitemfactory.xml" />
<section>
<xi:include href="xml/gtksignallistitemfactory.xml" />
<xi:include href="xml/gtkbuilderlistitemfactory.xml" />
</section>
<xi:include href="xml/gtklistview.xml" />
<xi:include href="xml/gtkgridview.xml" />
<xi:include href="xml/gtkcolumnview.xml" />
<xi:include href="xml/gtkcolumnviewcolumn.xml" />
<xi:include href="xml/gtkdropdown.xml" />
</chapter>
<chapter id="Trees">
<xi:include href="xml/gtktreelistrow.xml" />
<xi:include href="xml/gtktreelistmodel.xml" />
<xi:include href="xml/gtktreelistrowsorter.xml" />
<xi:include href="xml/gtktreeexpander.xml" />
</chapter>
<chapter id="Application">
@@ -65,11 +102,13 @@
<title>Interface builder</title>
<xi:include href="xml/gtkbuilder.xml" />
<xi:include href="xml/gtkbuildable.xml" />
<xi:include href="xml/gtkbuilderscope.xml" />
</chapter>
<chapter id="WindowWidgets">
<title>Windows</title>
<xi:include href="xml/gtkroot.xml" />
<xi:include href="xml/gtknative.xml" />
<xi:include href="xml/gtkwindow.xml" />
<xi:include href="xml/gtkdialog.xml" />
<xi:include href="xml/gtkmessagedialog.xml" />
@@ -148,7 +187,6 @@
<xi:include href="xml/gtkscalebutton.xml" />
<xi:include href="xml/gtkvolumebutton.xml" />
<xi:include href="xml/gtklockbutton.xml" />
<xi:include href="xml/gtkmodelbutton.xml" />
</chapter>
<chapter id="NumericEntry">
@@ -167,7 +205,7 @@
<chapter id="TextWidgetObjects">
<title>Multiline Text Editor</title>
<xi:include href="xml/text_widget.sgml" />
<xi:include href="xml/text_widget.xml" />
<xi:include href="xml/gtktextiter.xml" />
<xi:include href="xml/gtktextmark.xml" />
<xi:include href="xml/gtktextbuffer.xml" />
@@ -178,7 +216,7 @@
<chapter id="TreeWidgetObjects">
<title>Tree, List and Icon Grid Widgets</title>
<xi:include href="xml/tree_widget.sgml" />
<xi:include href="xml/tree_widget.xml" />
<xi:include href="xml/gtktreemodel.xml" />
<xi:include href="xml/gtktreeselection.xml" />
<xi:include href="xml/gtktreeviewcolumn.xml" />
@@ -228,6 +266,7 @@
<xi:include href="xml/gtkpopover.xml" />
<xi:include href="xml/gtkpopovermenu.xml" />
<xi:include href="xml/gtkpopovermenubar.xml" />
<xi:include href="xml/gtkdropdown.xml" />
</chapter>
<chapter id="SelectorWidgets">
@@ -406,12 +445,12 @@
<part id="platform-support">
<title>GTK Platform Support</title>
<xi:include href="building.sgml" />
<xi:include href="xml/compiling.sgml" />
<xi:include href="running.sgml" />
<xi:include href="x11.sgml" />
<xi:include href="windows.sgml" />
<xi:include href="osx.sgml" />
<xi:include href="building.xml" />
<xi:include href="xml/compiling.xml" />
<xi:include href="running.xml" />
<xi:include href="x11.xml" />
<xi:include href="windows.xml" />
<xi:include href="osx.xml" />
<xi:include href="broadway.xml" />
<xi:include href="wayland.xml" />
</part>

File diff suppressed because it is too large Load Diff

View File

@@ -9,6 +9,7 @@ gtk_accessible_get_type
gtk_actionable_get_type
gtk_action_bar_get_type
gtk_adjustment_get_type
gtk_any_filter_get_type
gtk_app_chooser_get_type
gtk_app_chooser_button_get_type
gtk_app_chooser_dialog_get_type
@@ -22,8 +23,11 @@ gtk_bin_get_type
gtk_bin_layout_get_type
gtk_box_get_type
gtk_box_layout_get_type
gtk_builder_get_type
gtk_buildable_get_type
gtk_builder_cscope_get_type
gtk_builder_get_type
gtk_builder_list_item_factory_get_type
gtk_builder_scope_get_type
gtk_button_get_type
gtk_calendar_get_type
gtk_cell_area_get_type
@@ -47,6 +51,8 @@ gtk_color_button_get_type
gtk_color_chooser_get_type
gtk_color_chooser_dialog_get_type
gtk_color_chooser_widget_get_type
gtk_column_view_get_type
gtk_column_view_column_get_type
gtk_combo_box_get_type
gtk_combo_box_text_get_type
gtk_constraint_get_type
@@ -54,9 +60,13 @@ gtk_constraint_guide_get_type
gtk_constraint_layout_get_type
gtk_constraint_target_get_type
gtk_container_get_type
gtk_custom_sorter_get_type
gtk_css_provider_get_type
gtk_custom_filter_get_type
gtk_dialog_get_type
gtk_directory_list_get_type
gtk_drawing_area_get_type
gtk_drop_down_get_type
gtk_editable_get_type
gtk_entry_buffer_get_type
gtk_entry_completion_get_type
@@ -66,14 +76,18 @@ gtk_event_controller_key_get_type
gtk_event_controller_legacy_get_type
gtk_event_controller_motion_get_type
gtk_event_controller_scroll_get_type
gtk_every_filter_get_type
gtk_expander_get_type
gtk_file_chooser_button_get_type
gtk_file_chooser_dialog_get_type
gtk_file_chooser_get_type
gtk_file_chooser_widget_get_type
gtk_file_filter_get_type
gtk_filter_get_type
gtk_filter_list_model_get_type
gtk_fixed_get_type
gtk_fixed_layout_get_type
gtk_flatten_list_model_get_type
gtk_flow_box_get_type
gtk_flow_box_child_get_type
gtk_font_button_get_type
@@ -95,6 +109,7 @@ gtk_gl_area_get_type
gtk_grid_get_type
gtk_grid_layout_child_get_type
gtk_grid_layout_get_type
gtk_grid_view_get_type
gtk_header_bar_get_type
gtk_icon_theme_get_type
gtk_icon_view_get_type
@@ -107,10 +122,14 @@ gtk_label_get_type
gtk_layout_child_get_type
gtk_layout_manager_get_type
gtk_link_button_get_type
gtk_list_item_get_type
gtk_list_item_factory_get_type
gtk_list_store_get_type
gtk_list_box_get_type
gtk_list_box_row_get_type
gtk_list_view_get_type
gtk_lock_button_get_type
gtk_map_list_model_get_type
gtk_media_controls_get_type
gtk_media_file_get_type
gtk_media_stream_get_type
@@ -121,10 +140,14 @@ gtk_menu_item_get_type
gtk_menu_shell_get_type
gtk_menu_tool_button_get_type
gtk_message_dialog_get_type
gtk_model_button_get_type
gtk_mount_operation_get_type
gtk_multi_filter_get_type
gtk_multi_sorter_get_type
gtk_native_get_type
gtk_no_selection_get_type
gtk_notebook_get_type
gtk_notebook_page_get_type
gtk_numeric_sorter_get_type
gtk_orientable_get_type
gtk_overlay_get_type
gtk_pad_controller_get_type
@@ -169,9 +192,13 @@ gtk_shortcuts_window_get_type
gtk_shortcuts_section_get_type
gtk_shortcuts_group_get_type
gtk_shortcuts_shortcut_get_type
gtk_signal_list_item_factory_get_type
gtk_single_selection_get_type
gtk_size_group_get_type
gtk_slice_list_model_get_type
gtk_snapshot_get_type
gtk_sort_list_model_get_type
gtk_sorter_get_type
gtk_spin_button_get_type
gtk_spinner_get_type
gtk_stack_get_type
@@ -179,6 +206,8 @@ gtk_stack_page_get_type
gtk_stack_sidebar_get_type
gtk_stack_switcher_get_type
gtk_statusbar_get_type
gtk_string_filter_get_type
gtk_string_sorter_get_type
gtk_switch_get_type
gtk_level_bar_get_type
gtk_style_context_get_type
@@ -198,6 +227,10 @@ gtk_tool_button_get_type
gtk_tool_item_get_type
gtk_tree_drag_dest_get_type
gtk_tree_drag_source_get_type
gtk_tree_expander_get_type
gtk_tree_list_model_get_type
gtk_tree_list_row_get_type
gtk_tree_list_row_sorter_get_type
gtk_tree_model_filter_get_type
gtk_tree_model_get_type
gtk_tree_model_sort_get_type

View File

@@ -21,6 +21,13 @@ private_headers = [
'gtkcolorplaneprivate.h',
'gtkcolorscaleprivate.h',
'gtkcolorswatchprivate.h',
'gtkcolumnviewcellprivate.h',
'gtkcolumnviewcolumnprivate.h',
'gtkcolumnviewlayoutprivate.h',
'gtkcolumnlistitemfactoryprivate.h',
'gtkcolumviewprivate.h',
'gtkcolumnviewsorterprivate.h',
'gtkcolumnviewtitleprivate.h',
'gtkcomboboxprivate.h',
'gtkcontainerprivate.h',
'gtkconstraintexpressionprivate.h',
@@ -131,6 +138,11 @@ private_headers = [
'gtkimmoduleprivate.h',
'gtkkineticscrollingprivate.h',
'gtklabelprivate.h',
'gtklistbaseprivate.h',
'gtklistitemprivate.h',
'gtklistitemfactoryprivate.h',
'gtklistitemmanagerprivate.h',
'gtklistitemwidgetprivate.h',
'gtklockbuttonprivate.h',
'gtkmagnifierprivate.h',
'gtkmediafileprivate.h',
@@ -178,8 +190,10 @@ private_headers = [
'gtktextchildprivate.h',
'gtktextdisplayprivate.h',
'gtktexthandleprivate.h',
'gtktexthistoryprivate.h',
'gtktextiterprivate.h',
'gtktextlayoutprivate.h',
'gtktextlinedisplaycacheprivate.h',
'gtktextmarkprivate.h',
'gtktexttagprivate.h',
'gtktextviewprivate.h',
@@ -342,8 +356,8 @@ images = [
content_files = [
'actions.xml',
'broadway.xml',
'building.sgml',
'compiling.sgml',
'building.xml',
'compiling.xml',
'css-overview.xml',
'css-properties.xml',
'drawing-model.xml',
@@ -361,31 +375,31 @@ content_files = [
'input-handling.xml',
'migrating-2to4.xml',
'migrating-3to4.xml',
'osx.sgml',
'other_software.sgml',
'osx.xml',
'other_software.xml',
'overview.xml',
'question_index.sgml',
'resources.sgml',
'running.sgml',
'text_widget.sgml',
'tree_widget.sgml',
'question_index.xml',
'resources.xml',
'running.xml',
'text_widget.xml',
'tree_widget.xml',
'visual_index.xml',
'wayland.xml',
'windows.sgml',
'x11.sgml',
'windows.xml',
'x11.xml',
]
expand_content_files = [
'actions.xml',
'compiling.sgml',
'compiling.xml',
'drawing-model.xml',
'glossary.xml',
'input-handling.xml',
'migrating-2to4.xml',
'migrating-3to4.xml',
'question_index.sgml',
'text_widget.sgml',
'tree_widget.sgml',
'question_index.xml',
'text_widget.xml',
'tree_widget.xml',
]
types_conf = configuration_data()

View File

@@ -813,6 +813,44 @@
</para>
</section>
<section>
<title>GtkEntryBuffer ::deleted-text has changed</title>
<para>
To allow signal handlers to access the deleted text before it
has been deleted #GtkEntryBuffer::deleted-text has changed from
%G_SIGNAL_RUN_FIRST to %G_SIGNAL_RUN_LAST. The default handler
removes the text from the #GtkEntryBuffer.
</para>
<para>
To adapt existing code, use g_signal_connect_after() or
%G_CONNECT_AFTER when using g_signal_connect_data() or
g_signal_connect_object().
</para>
</section>
<section>
<title>The "iconified" window state has been renamed to "minimized"</title>
<para>
The <literal>GDK_SURFACE_STATE_ICONIFIED</literal> value of the
#GdkSurfaceState enumeration is now %GDK_SURFACE_STATE_MINIMIZED.
</para>
<para>
The #GdkSurface functions <function>gdk_surface_iconify()</function>
and <function>gdk_surface_deiconify()</function> have been renamed to
gdk_surface_minimize() and gdk_surface_unminimize(), respectively.
</para>
<para>
The corresponding #GtkWindow functions <function>gtk_window_iconify()</function>
and <function>gtk_window_deiconify()</function> have been renamed
to gtk_window_minimize() and gtk_window_unminimize(), respectively.
</para>
<para>
The behavior of the minimization and unminimization operations have
not been changed, and they still require support from the underlying
windowing system.
</para>
</section>
</section>
</chapter>

View File

@@ -112,6 +112,16 @@ multiple bytes in UTF-8, and the two-character sequence "\r\n" is also
considered a line separator.
</para>
<para>
Text buffers support undo and redo if gtk_text_buffer_set_undo_enabled()
has been set to %TRUE. Use gtk_text_buffer_undo() or gtk_text_buffer_redo()
to perform the necessary action. Note that these operations are ignored if
the buffer is not editable. Developers may want some operations to not be
undoable. To do this, wrap your changes in
gtk_text_buffer_begin_irreversible_action() and
gtk_text_buffer_end_irreversible_action().
</para>
</refsect1>

View File

@@ -138,7 +138,7 @@ url="http://www.freedesktop.org/standards/">convention</ulink>.
<para>
GTK has functions for asking the window manager to do various things;
see for example <link
linkend="gtk-window-iconify">gtk_window_iconify()</link> or <link
linkend="gtk-window-minimize">gtk_window_minimize()</link> or <link
linkend="gtk-window-maximize">gtk_window_maximize()</link> or <link
linkend="gtk-window-set-decorated">gtk_window_set_decorated()</link>.
Keep in mind that most window managers <emphasis>will</emphasis> ignore

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,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

@@ -25,8 +25,8 @@
#ifndef __GDK_BROADWAY_CURSOR_H__
#define __GDK_BROADWAY_CURSOR_H__
#if !defined (__GDKBROADWAY_H_INSIDE__) && !defined (GDK_COMPILATION)
#error "Only <gdk/gdkbroadway.h> can be included directly."
#if !defined (__GDKBROADWAY_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gdk/broadway/gdkbroadway.h> can be included directly."
#endif
#include <gdk/gdk.h>
@@ -40,7 +40,7 @@ G_BEGIN_DECLS
#define GDK_IS_BROADWAY_CURSOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_BROADWAY_CURSOR))
#define GDK_BROADWAY_CURSOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_BROADWAY_CURSOR, GdkBroadwayCursorClass))
#ifdef GDK_COMPILATION
#ifdef GTK_COMPILATION
typedef struct _GdkBroadwayCursor GdkBroadwayCursor;
#else
typedef GdkCursor GdkBroadwayCursor;

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