Compare commits
190 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4ab2f28f8e | |||
| da0cf5fbff | |||
| c60395cfc9 | |||
| cb2ba0abc0 | |||
| e8e21e7012 | |||
| 97ad2d7897 | |||
| f9592e3c9a | |||
| fdd57076eb | |||
| 994a1bc016 | |||
| 1d178b5464 | |||
| fe6aa38522 | |||
| b2e7ebf6b9 | |||
| d4968d8140 | |||
| adc4f0cdd9 | |||
| 9c0bf55a17 | |||
| 5fc83197dd | |||
| c2c976cb6a | |||
| b1a59dad5e | |||
| 5fef6ed4dc | |||
| 6a11e0545d | |||
| 456321c2d7 | |||
| 14a63693de | |||
| 6f32b6fadc | |||
| 3431a5346d | |||
| 1dd823f6f6 | |||
| 479b69a8bf | |||
| 7cecc8e524 | |||
| c6894cd606 | |||
| f7f63ae3ee | |||
| 117c86d08a | |||
| fb08a26acd | |||
| f326c0eac8 | |||
| 4dc01aca43 | |||
| 6c79fb72bd | |||
| e399798da8 | |||
| 8eeb379f7c | |||
| 67595f3614 | |||
| 43b42704c5 | |||
| 3c7fbe237d | |||
| 0d49b97fce | |||
| 286d3466a1 | |||
| 78189bf5e0 | |||
| 210451e86f | |||
| 3f397d6b38 | |||
| 2f0a5dd541 | |||
| e9e4c8b168 | |||
| b84b933cac | |||
| 51bbb76d35 | |||
| 3605e6c900 | |||
| cf6695088e | |||
| 851b631c4e | |||
| 0f9c43b569 | |||
| 327a164744 | |||
| a30b84f522 | |||
| 0122a9da8e | |||
| 2d35f7a8e1 | |||
| 61f47829ba | |||
| 2d29c4a43f | |||
| 01f7ed1d07 | |||
| d90e3670ce | |||
| 6146bf7a32 | |||
| ea98c61f3c | |||
| 9c2eb4f233 | |||
| cb99cd2052 | |||
| 41e8d3df6d | |||
| 01fe4ce7f4 | |||
| 1349292e47 | |||
| 8f06590712 | |||
| 17b9733372 | |||
| a021dc793c | |||
| 032636f3ea | |||
| 4f9a71d286 | |||
| e30d5acc60 | |||
| b01c69a018 | |||
| 4dcd49352b | |||
| 11c9c70673 | |||
| c67eb10fcb | |||
| f47e578737 | |||
| 8cb78d82d6 | |||
| b8d2806417 | |||
| 59c3e7bfe8 | |||
| 402985077b | |||
| e9f182e37a | |||
| 13858fde29 | |||
| ef759ef19d | |||
| 51a31f9098 | |||
| 0e4b460574 | |||
| 1f17efb81c | |||
| d35596fe92 | |||
| b957e16695 | |||
| b72cf9129c | |||
| 23031defde | |||
| f1ce727b06 | |||
| ca120a98e5 | |||
| c71fea568f | |||
| d5310f9367 | |||
| a082f4d804 | |||
| 8dc090b9b1 | |||
| c69d2e4254 | |||
| f3685c5e88 | |||
| a8a41b52ad | |||
| af49dd33cf | |||
| 06c8e8fa43 | |||
| 95ce57443c | |||
| 9544ae08af | |||
| 648ef7f7fa | |||
| 661f24736b | |||
| 174664b235 | |||
| 8c68050af8 | |||
| b7063509f8 | |||
| 0032b2dc5a | |||
| d9b9ba5da0 | |||
| 8ca13c4679 | |||
| 316d450421 | |||
| c7b4dd5f9d | |||
| e8d4bfd04b | |||
| e253a414b0 | |||
| ac8817d34b | |||
| c630804647 | |||
| 43f1ac2b8f | |||
| ebbc7791dd | |||
| 2b4c9983da | |||
| f354cef61b | |||
| 8fbd6e2edc | |||
| e64c1f8929 | |||
| 1df8d18ad2 | |||
| 433c0c2134 | |||
| 627685e2a2 | |||
| 72cd8b4dab | |||
| d6684b5748 | |||
| 7523b25942 | |||
| 6acc8c0817 | |||
| 9a42942afb | |||
| 1e1cf89e4f | |||
| 5ad618cb95 | |||
| 77e0f18eda | |||
| 852cbb62b8 | |||
| f15bc7818e | |||
| 655c781b6e | |||
| f0f07ad6d8 | |||
| 179004f0a7 | |||
| e58b19db04 | |||
| 315261260c | |||
| 3450388ff0 | |||
| 009aadf378 | |||
| 7bbbb01ff5 | |||
| a44d6816d3 | |||
| 7846bedebd | |||
| 87922575d3 | |||
| 0c1423d962 | |||
| ca0a18918c | |||
| 5322420145 | |||
| 66007d0ab6 | |||
| 15bba87e9a | |||
| 8ff96b3bb2 | |||
| 86688c6fde | |||
| aec62e1c10 | |||
| d7f43c30a3 | |||
| 0bd173e3d8 | |||
| 443459b52e | |||
| d82257e1c8 | |||
| b88c0d7387 | |||
| 6d77bf66ac | |||
| b8e4adfff9 | |||
| 361754b063 | |||
| b5912e61fd | |||
| e5b384f537 | |||
| b164df7450 | |||
| 6186429f5f | |||
| a8123bf95e | |||
| af6f874060 | |||
| b0cf4d057d | |||
| 71f1f768cc | |||
| 49511c7f42 | |||
| 85ccb93b9f | |||
| 24bac24602 | |||
| f83ba08f7f | |||
| c37b30f317 | |||
| 88cd26575d | |||
| e72a78c4e6 | |||
| 8ca73e3258 | |||
| 06f5b1e572 | |||
| 2e39c4bab8 | |||
| 57c4bcb369 | |||
| 9b91e06513 | |||
| 44ba055d03 | |||
| 32abb29b32 | |||
| a25e0a97d5 | |||
| 9d8e3be6d7 | |||
| 9ded1c0c99 |
@@ -1,3 +1,201 @@
|
||||
Overview of Changes in GTK+ 3.7 to 3.9
|
||||
======================================
|
||||
|
||||
* GtkFileChooser:
|
||||
- Always show fuse-mounted locations in shortcuts
|
||||
- GtkFileChooserButton has received a lot of fixes and tests have
|
||||
been added for many of them
|
||||
|
||||
* GtkWindow:
|
||||
- Initial support for client-side decorations has been added. This
|
||||
is going to be used by default under Wayland. To try it with other
|
||||
backends, set the GTK_CSD=1 environment variable.
|
||||
- gtk_window_set_titlebar: A new function that can set a custom,
|
||||
client-side titlebar on toplevel windows.
|
||||
|
||||
* Wayland:
|
||||
- Use client-side decorations
|
||||
- Implement maximization
|
||||
- Improve cursor handling
|
||||
- Improve multi-monitor handling
|
||||
- Support most GtkSettings (for now by reading GSettings directly)
|
||||
- Complete the keymap implementation
|
||||
- Add support for custom surfaces
|
||||
- Implement animated cursors
|
||||
- Support the WAYLAND_SOCKET environment variable
|
||||
- Implement frame synchronizatio
|
||||
- Document Wayland-specific APIs
|
||||
|
||||
* Broadway:
|
||||
- Improve window size handling
|
||||
- Implement frame synchronization
|
||||
- Add support for password authentication
|
||||
|
||||
* New APIs, widgets, feature additions:
|
||||
- GtkHeaderBar is a new widget similar to a GtkBox, with the extra
|
||||
feature that it can center a child (typically a title), independent
|
||||
of the other content.
|
||||
- GtkPlacesSidebar is the sidebar widget in the file chooser, exported
|
||||
as a public widget - it will be shared with nautilus.
|
||||
- GtkStack is an alternative to GtkNotebook for showing one of several
|
||||
child widgets at a time. It supports animated transitions. Tabs are
|
||||
not built into this widgets, but instead provided by the separate
|
||||
GtkStackSwitcher widget.
|
||||
- GtkRevealer is a new new widget that can hide or show its child
|
||||
in an animated fashion.
|
||||
- GtkMenuTracker is a helper object that makes dealing with
|
||||
GMenuModels easier and more efficient.
|
||||
- gtk_grid_remove_row/column: New functions to remove whole rows
|
||||
or columns from a GtkGrid
|
||||
- Support for composite children has been added to GtkWidget. This
|
||||
allows to create complex widgets from GtkBuilder ui files. All
|
||||
complex GTK+ widgets have been converted to use this facility.
|
||||
- Baseline support was added to the GTK+ size allocation machinery.
|
||||
Widgets can now export the baseline of the text they contain,
|
||||
and containers can align their children wrt to their baselines.
|
||||
|
||||
|
||||
* Known problems, feature removals, compatibility caveats:
|
||||
- Handling of window size is currently in flux, and there are
|
||||
some known problems with sizes unintentionally changing
|
||||
- Support for the Motif DND protocol has been dropped
|
||||
- Client-side decorations still have some issues when drawing
|
||||
directly on toplevel windows or setting their background
|
||||
- Support for multiple screens per display has been removed. This
|
||||
was only ever supported on X11, and is an exceedingly rare setup
|
||||
nowadays. The display-screen relation is now 1:1, and we will do
|
||||
some more simplification of displaymanager/display/screen/monitor
|
||||
APIs.
|
||||
- gdk_window_get_display has been deprecated
|
||||
- gtk_widget_push_composite_child has been deprecated - this was
|
||||
used for anything
|
||||
- GtkSwitch has been changed to draw focus internally, instead of
|
||||
reserving space outside the switch for it. This may require some
|
||||
application adjustment where margins were tweaked to 'correct'
|
||||
the alignment of switches manually
|
||||
|
||||
* Printing:
|
||||
- Avoid blocking when looking for avahi printers
|
||||
- Don't link against avahi-gobject, use D-Bus directly
|
||||
|
||||
* Bugs fixed:
|
||||
504901 GtkCellRendererCombo requires click-and-hold
|
||||
586367 In local_only mode, file chooser should return native pa...
|
||||
671939 [regression] crash on exit
|
||||
672018 Need API to set global application state (busy, counters...
|
||||
674051 Scrolling zoom in view - incorrect image display
|
||||
674759 GtkLabel: wrong value of "mnemonic-keyval" when "use-mar...
|
||||
675571 (out) or (inout) annotation possibly missing for gtk_men...
|
||||
675649 gtk-demo: Fix typo
|
||||
680241 Instructions on how to build a GTK app won't work with r...
|
||||
681446 gtkdnd memory leak
|
||||
685419 gtkprintbackendfile: Infinite loop in _cairo_write()
|
||||
685420 Critical warnings when GtkPrintJob is released too early
|
||||
688820 GIcon is a bad interface
|
||||
688896 Add documentation for GtkWidget::show,hide,map,unmap,rea...
|
||||
690275 scrolling on other windows is applied when coming back (...
|
||||
691040 selection is reported incorrectly in file chooser button
|
||||
692871 Need to expose output information to make GdkScreen API ...
|
||||
694339 Fix build of GTK+ on Windows
|
||||
694465 Allow backends to fail during initialisation
|
||||
695200 Switching apps while a combobox open makes the parent wi...
|
||||
695228 GdkPixbuf:ERROR:gdk-pixbuf-animation.c:242:gdk_pixbuf_an...
|
||||
695278 Avoid passing a NULL title to setTitle
|
||||
695304 GtkTextView: don't popdown a bubble if we don't have one
|
||||
695312 Initial 'text' set in the non-numeric-only GtkSpinButton...
|
||||
695375 GtkEntryAccessible: also handle entry icon tooltip NULL ...
|
||||
695380 gtk_binding_entry_skip broken
|
||||
695391 wayland documentation section id is "gtk-osx"
|
||||
695473 treeview: fix a critical warning
|
||||
695476 Drop the Motif DND protocol
|
||||
695482 Universal Access panel appears jumbled and horrible afte...
|
||||
695493 testgtk: issues with the color selection example
|
||||
695495 testgtk: cursor example segfaults
|
||||
695497 testgtk: lack of key repeat
|
||||
695506 gtk-demo: link hovering unreliable
|
||||
695682 Cannot build docs for wayland-only build
|
||||
695714 Getting of printer info can hang
|
||||
695772 Different appearance of menus within Audacious
|
||||
695783 GtkApplication: Allow passing windows on non-X11 targets
|
||||
695861 Allow to use custom surfaces for GdkWindows in Wayland
|
||||
695874 GtkFontChooser docs
|
||||
695895 Fix the gtk3-demo demo program on Windows
|
||||
695945 implement minimize / maximize functionality
|
||||
695948 GtkFontButton sets wrong show-preview-entry
|
||||
695998 csd: enable shadows in the outer border
|
||||
696051 vertical grid lines in rtl mode
|
||||
696138 GtkWidget: some deprecation marks are missing
|
||||
696171 GtkAssistant highlighted font unreadable
|
||||
696202 Add GtkSpinner animation back to Win32 theme
|
||||
696232 win32: do not crash on invalid utf8 conversion
|
||||
696340 wayland: device list is populated async
|
||||
696370 GtkOverlay doesn't work on top of GtkClutterEmbed
|
||||
696429 wayland: Implement animated cursors
|
||||
696457 gnome-ostree build broken by 3a9de35a6cefddc09aaf000e523...
|
||||
696468 improve GMenuModel -> GtkMenu conversion
|
||||
696546 gtk_print_backend_cups_finalize() crashes if cups_get_pr...
|
||||
696553 Crash in avahi_create_browsers
|
||||
696561 GtkApplicationWindow rendering broken
|
||||
696608 css_image_value_parse: returning FALSE in pointer function
|
||||
696622 gtk option printer widget segfault in epiphany
|
||||
696623 GtkOverlay with a revealer produces warnings setting a m...
|
||||
696767 a pair of memory leaks
|
||||
696882 [regression] GtkWindow changes size after hide/show cycle
|
||||
697048 GtkTextView: small code improvements
|
||||
697144 Popup menu mnemonics fixes
|
||||
697196 gtk_notebook_set_tab_reorderable boolean handling
|
||||
697200 GtkWindow: notify::attached-to not emitted
|
||||
697263 Impossible to set window transparency on 3.8
|
||||
697275 gtk_window_set_default_size() doesn't work anymore
|
||||
697427 Unreferencing GtkStatusIcon object causes abort
|
||||
697673 Apps should connect only once when using Wayland
|
||||
697795 xi2: Improve pointer emulation debug reporting
|
||||
697886 dnd icon drawing broken on master
|
||||
697947 A lot of GTK+ apps fail to launch with error "desktop_she...
|
||||
698181 Document icon-shadow CSS property
|
||||
698433 Geometry management broken in GtkBin widgets
|
||||
698682 GtkSpinButton: don't constantly recreate style contexts f...
|
||||
698864 wayland: improve integration with GdkFrameClock
|
||||
699020 GtkImage: do not leak metrics in baseline align
|
||||
699225 typo: Modifed -> Modified
|
||||
|
||||
* Translation updates:
|
||||
Arabic
|
||||
Aragonese
|
||||
Assamese
|
||||
Belarusian
|
||||
Brazilian Portuguese
|
||||
British English
|
||||
Catalan
|
||||
Catalan (Valencian)
|
||||
Czech
|
||||
Danish
|
||||
Finnish
|
||||
French
|
||||
Galician
|
||||
German
|
||||
Greek
|
||||
Hindi
|
||||
Hungarian
|
||||
Indonesian
|
||||
Italian
|
||||
Kazakh
|
||||
Korean
|
||||
Latvian
|
||||
Malayalam
|
||||
Odia
|
||||
Persian
|
||||
Polish
|
||||
Punjabi
|
||||
Russian
|
||||
Serbian
|
||||
Simplified Chinese
|
||||
Slovenian
|
||||
Tajik
|
||||
Tamil
|
||||
Ukrainian
|
||||
|
||||
|
||||
Overview of Changes in GTK+ 3.7.12
|
||||
==================================
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
m4_define([gtk_major_version], [3])
|
||||
m4_define([gtk_minor_version], [9])
|
||||
m4_define([gtk_micro_version], [0])
|
||||
m4_define([gtk_micro_version], [1])
|
||||
m4_define([gtk_interface_age], [0])
|
||||
m4_define([gtk_binary_age],
|
||||
[m4_eval(100 * gtk_minor_version + gtk_micro_version)])
|
||||
@@ -1242,7 +1242,6 @@ if test "$have_gio_unix" = "yes"; then
|
||||
else
|
||||
GDK_GIO_PACKAGE=gio-2.0
|
||||
fi
|
||||
AM_CONDITIONAL(HAVE_GIO_UNIX, test "$have_gio_unix" = "yes")
|
||||
|
||||
# Check for Pango flags
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ demos = \
|
||||
pickers.c \
|
||||
pixbufs.c \
|
||||
printing.c \
|
||||
revealer.c \
|
||||
rotated_text.c \
|
||||
search_entry.c \
|
||||
sizegroup.c \
|
||||
@@ -86,7 +87,7 @@ gsettings_SCHEMAS = \
|
||||
@GSETTINGS_RULES@
|
||||
|
||||
demos.h: @REBUILD@ $(demos) geninclude.pl
|
||||
$(AM_V_GEN) (here=`pwd` ; cd $(srcdir) && $(PERL) $$here/geninclude.pl $(demos)) > demos.h
|
||||
$(AM_V_GEN) (here=`pwd` ; cd $(srcdir) && $(PERL) $$here/geninclude.pl $(demos)) > demos.h
|
||||
|
||||
gtk3_demo_SOURCES = \
|
||||
$(demos) \
|
||||
@@ -112,6 +113,7 @@ RESOURCES= $(demos) \
|
||||
demo.ui \
|
||||
menus.ui \
|
||||
stack.ui \
|
||||
revealer.ui \
|
||||
theming.ui \
|
||||
alphatest.png \
|
||||
apple-red.png \
|
||||
|
||||
@@ -58,6 +58,9 @@
|
||||
<gresource prefix="/stack">
|
||||
<file>stack.ui</file>
|
||||
</gresource>
|
||||
<gresource prefix="/revealer">
|
||||
<file>revealer.ui</file>
|
||||
</gresource>
|
||||
<gresource prefix="/images">
|
||||
<file>alphatest.png</file>
|
||||
<file>floppybuddy.gif</file>
|
||||
@@ -110,6 +113,7 @@
|
||||
<file>pickers.c</file>
|
||||
<file>pixbufs.c</file>
|
||||
<file>printing.c</file>
|
||||
<file>revealer.c</file>
|
||||
<file>rotated_text.c</file>
|
||||
<file>search_entry.c</file>
|
||||
<file>sizegroup.c</file>
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
/* Revealer
|
||||
*
|
||||
* GtkRevealer is a container that animates showing and hiding
|
||||
* of its sole child with nice transitions.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
static GtkBuilder *builder;
|
||||
static gint count = 0;
|
||||
|
||||
static void
|
||||
change_direction (GtkRevealer *revealer)
|
||||
{
|
||||
gboolean revealed;
|
||||
|
||||
revealed = gtk_revealer_get_child_revealed (revealer);
|
||||
gtk_revealer_set_reveal_child (revealer, !revealed);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
reveal_one (gpointer data)
|
||||
{
|
||||
gchar *name;
|
||||
GtkRevealer *revealer;
|
||||
|
||||
name = g_strdup_printf ("revealer%d", count);
|
||||
revealer = (GtkRevealer *)gtk_builder_get_object (builder, name);
|
||||
|
||||
gtk_revealer_set_reveal_child (revealer, TRUE);
|
||||
|
||||
g_signal_connect (revealer, "notify::child-revealed",
|
||||
G_CALLBACK (change_direction), NULL);
|
||||
count++;
|
||||
|
||||
return count < 9;
|
||||
}
|
||||
|
||||
static void
|
||||
response_cb (GtkWidget *dialog,
|
||||
gint response_id,
|
||||
gpointer data)
|
||||
{
|
||||
gtk_widget_destroy (dialog);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_revealer (GtkWidget *do_widget)
|
||||
{
|
||||
static GtkWidget *window = NULL;
|
||||
GError *err = NULL;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
builder = gtk_builder_new ();
|
||||
gtk_builder_add_from_resource (builder, "/revealer/revealer.ui", &err);
|
||||
if (err)
|
||||
{
|
||||
g_error ("ERROR: %s\n", err->message);
|
||||
return NULL;
|
||||
}
|
||||
gtk_builder_connect_signals (builder, NULL);
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "dialog1"));
|
||||
gtk_window_set_screen (GTK_WINDOW (window),
|
||||
gtk_widget_get_screen (do_widget));
|
||||
g_signal_connect (window, "destroy",
|
||||
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||
g_signal_connect (window, "response", G_CALLBACK (response_cb), NULL);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
{
|
||||
count = 0;
|
||||
g_timeout_add (690, reveal_one, NULL);
|
||||
gtk_widget_show_all (window);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_widget_destroy (window);
|
||||
window = NULL;
|
||||
}
|
||||
|
||||
|
||||
return window;
|
||||
}
|
||||
@@ -0,0 +1,223 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<!-- interface-requires gtk+ 3.6 -->
|
||||
<object class="GtkDialog" id="dialog1">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="border_width">5</property>
|
||||
<property name="type_hint">dialog</property>
|
||||
<property name="default_width">300</property>
|
||||
<property name="default_height">300</property>
|
||||
<property name="title">Revealer</property>
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkBox" id="dialog-vbox1">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">2</property>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkButtonBox" id="dialog-action_area1">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="layout_style">end</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="button1">
|
||||
<property name="label">gtk-close</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkGrid" id="grid1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">center</property>
|
||||
<child>
|
||||
<object class="GtkRevealer" id="revealer0">
|
||||
<property name="visible">True</property>
|
||||
<property name="transition-duration">2000</property>
|
||||
<property name="transition-type">crossfade</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="image0">
|
||||
<property name="visible">True</property>
|
||||
<property name="icon-name">face-cool-symbolic</property>
|
||||
<property name="icon-size">6</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">2</property>
|
||||
<property name="top-attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRevealer" id="revealer1">
|
||||
<property name="visible">True</property>
|
||||
<property name="transition-duration">2000</property>
|
||||
<property name="transition-type">slide-up</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="image1">
|
||||
<property name="visible">True</property>
|
||||
<property name="icon-name">face-cool-symbolic</property>
|
||||
<property name="icon-size">6</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">2</property>
|
||||
<property name="top-attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRevealer" id="revealer2">
|
||||
<property name="visible">True</property>
|
||||
<property name="transition-duration">2000</property>
|
||||
<property name="transition-type">slide-right</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="image2">
|
||||
<property name="visible">True</property>
|
||||
<property name="icon-name">face-cool-symbolic</property>
|
||||
<property name="icon-size">6</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">3</property>
|
||||
<property name="top-attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRevealer" id="revealer3">
|
||||
<property name="visible">True</property>
|
||||
<property name="transition-duration">2000</property>
|
||||
<property name="transition-type">slide-down</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="image3">
|
||||
<property name="visible">True</property>
|
||||
<property name="icon-name">face-cool-symbolic</property>
|
||||
<property name="icon-size">6</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">2</property>
|
||||
<property name="top-attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRevealer" id="revealer4">
|
||||
<property name="visible">True</property>
|
||||
<property name="transition-duration">2000</property>
|
||||
<property name="transition-type">slide-left</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="image4">
|
||||
<property name="visible">True</property>
|
||||
<property name="icon-name">face-cool-symbolic</property>
|
||||
<property name="icon-size">6</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRevealer" id="revealer5">
|
||||
<property name="visible">True</property>
|
||||
<property name="transition-duration">2000</property>
|
||||
<property name="transition-type">slide-up</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="image5">
|
||||
<property name="visible">True</property>
|
||||
<property name="icon-name">face-cool-symbolic</property>
|
||||
<property name="icon-size">6</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">2</property>
|
||||
<property name="top-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRevealer" id="revealer6">
|
||||
<property name="visible">True</property>
|
||||
<property name="transition-duration">2000</property>
|
||||
<property name="transition-type">slide-right</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="image6">
|
||||
<property name="visible">True</property>
|
||||
<property name="icon-name">face-cool-symbolic</property>
|
||||
<property name="icon-size">6</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">4</property>
|
||||
<property name="top-attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRevealer" id="revealer7">
|
||||
<property name="visible">True</property>
|
||||
<property name="transition-duration">2000</property>
|
||||
<property name="transition-type">slide-down</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="image7">
|
||||
<property name="visible">True</property>
|
||||
<property name="icon-name">face-cool-symbolic</property>
|
||||
<property name="icon-size">6</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">2</property>
|
||||
<property name="top-attach">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRevealer" id="revealer8">
|
||||
<property name="visible">True</property>
|
||||
<property name="transition-duration">2000</property>
|
||||
<property name="transition-type">slide-left</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="image8">
|
||||
<property name="visible">True</property>
|
||||
<property name="icon-name">face-cool-symbolic</property>
|
||||
<property name="icon-size">6</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<action-widgets>
|
||||
<action-widget response="0">button1</action-widget>
|
||||
</action-widgets>
|
||||
</object>
|
||||
</interface>
|
||||
@@ -78,6 +78,35 @@ on_page_toggled (GtkToggleButton *button,
|
||||
gtk_notebook_set_current_page (pages, page);
|
||||
}
|
||||
|
||||
static void
|
||||
spin_value_changed (GtkAdjustment *adjustment, GtkWidget *label)
|
||||
{
|
||||
GtkWidget *w;
|
||||
gint v;
|
||||
gchar *text;
|
||||
|
||||
v = (int)gtk_adjustment_get_value (adjustment);
|
||||
|
||||
if ((v % 3) == 0)
|
||||
{
|
||||
text = g_strdup_printf ("%d is a multiple of 3", v);
|
||||
gtk_label_set_label (GTK_LABEL (label), text);
|
||||
g_free (text);
|
||||
}
|
||||
|
||||
w = gtk_widget_get_ancestor (label, GTK_TYPE_REVEALER);
|
||||
gtk_revealer_set_reveal_child (GTK_REVEALER (w), (v % 3) == 0);
|
||||
}
|
||||
|
||||
static void
|
||||
dismiss (GtkWidget *button)
|
||||
{
|
||||
GtkWidget *w;
|
||||
|
||||
w = gtk_widget_get_ancestor (button, GTK_TYPE_REVEALER);
|
||||
gtk_revealer_set_reveal_child (GTK_REVEALER (w), FALSE);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
@@ -86,6 +115,7 @@ main (int argc, char *argv[])
|
||||
GtkWidget *widget;
|
||||
GtkWidget *notebook;
|
||||
gboolean dark = FALSE;
|
||||
GtkAdjustment *adj;
|
||||
|
||||
gtk_init (&argc, &argv);
|
||||
|
||||
@@ -114,6 +144,14 @@ main (int argc, char *argv[])
|
||||
widget = (GtkWidget*) gtk_builder_get_object (builder, "aboutmenuitem");
|
||||
g_signal_connect (widget, "activate", G_CALLBACK (show_about), window);
|
||||
|
||||
widget = (GtkWidget*) gtk_builder_get_object (builder, "page2dismiss");
|
||||
g_signal_connect (widget, "clicked", G_CALLBACK (dismiss), NULL);
|
||||
|
||||
widget = (GtkWidget*) gtk_builder_get_object (builder, "page2note");
|
||||
adj = (GtkAdjustment *) gtk_builder_get_object (builder, "adjustment2");
|
||||
g_signal_connect (adj, "value-changed",
|
||||
G_CALLBACK (spin_value_changed), widget);
|
||||
|
||||
g_object_unref (G_OBJECT (builder));
|
||||
|
||||
gtk_widget_show (window);
|
||||
|
||||
@@ -54,6 +54,23 @@ Vestibulum in tortor diam, quis aliquet quam. Praesent ut justo neque, tempus ru
|
||||
Duis eu lectus quam. Vivamus eget metus a mauris molestie venenatis pulvinar eleifend nisi.
|
||||
Nulla facilisi. Pellentesque at dolor sit amet purus dapibus pulvinar molestie quis neque.
|
||||
Suspendisse feugiat quam quis dolor accumsan cursus. </property>
|
||||
</object>
|
||||
<object class="GtkTextBuffer" id="textbuffer2">
|
||||
<property name="text">* Translation updates:
|
||||
Aragonese
|
||||
Assamese
|
||||
Basque
|
||||
Brazilian Portuguese
|
||||
Dutch
|
||||
German
|
||||
Hebrew
|
||||
Hungarian
|
||||
Polish
|
||||
Portuguese
|
||||
Serbian
|
||||
Slovenian
|
||||
Spanish
|
||||
Uyghur</property>
|
||||
</object>
|
||||
<object class="GtkAccelGroup" id="accelgroup1"/>
|
||||
<object class="GtkWindow" id="window">
|
||||
@@ -2146,30 +2163,158 @@ Suspendisse feugiat quam quis dolor accumsan cursus. </property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="page2">
|
||||
<object class="GtkOverlay" id="page2">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">6</property>
|
||||
<property name="border-width">6</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="page2box1">
|
||||
<child type="overlay">
|
||||
<object class="GtkRevealer" id="page2revealer">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">horizontal</property>
|
||||
<property name="spacing">4</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">start</property>
|
||||
<child>
|
||||
<object class="GtkSpinButton" id="verticalspin1">
|
||||
<object class="GtkFrame" id="page2frame">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="adjustment">adjustment2</property>
|
||||
<property name="margin-top">2</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="page2box">
|
||||
<property name="visible">True</property>
|
||||
<property name="margin-top">10</property>
|
||||
<property name="margin-bottom">10</property>
|
||||
<property name="margin-left">10</property>
|
||||
<property name="margin-right">10</property>
|
||||
<property name="spacing">20</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="page2note">
|
||||
<property name="visible">True</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="label">NEWS!</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="page2dismiss">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="page2dismissi">
|
||||
<property name="visible">True</property>
|
||||
<property name="icon-name">window-close-symbolic</property>
|
||||
<property name="icon-size">0</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkGrid" id="page2grid">
|
||||
<property name="visible">True</property>
|
||||
<property name="column-homogeneous">True</property>
|
||||
<property name="row-spacing">6</property>
|
||||
<property name="column-spacing">6</property>
|
||||
<property name="border-width">6</property>
|
||||
<child>
|
||||
<object class="GtkSpinButton" id="verticalspin2">
|
||||
<object class="GtkBox" id="page2box1">
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="adjustment">adjustment1</property>
|
||||
<property name="orientation">horizontal</property>
|
||||
<property name="spacing">4</property>
|
||||
<child>
|
||||
<object class="GtkSpinButton" id="verticalspin1">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="adjustment">adjustment2</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSpinButton" id="verticalspin2">
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="adjustment">adjustment1</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="filler1">
|
||||
<property name="visible">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="filler2">
|
||||
<property name="visible">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">2</property>
|
||||
<property name="top-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStackSwitcher" id="switcher">
|
||||
<property name="visible">True</property>
|
||||
<property name="stack">stack</property>
|
||||
<property name="halign">center</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFrame" id="frame">
|
||||
<property name="visible">True</property>
|
||||
<property name="hexpand">False</property>
|
||||
<child>
|
||||
<object class="GtkStack" id="stack">
|
||||
<property name="visible">True</property>
|
||||
<property name="transition-type">crossfade</property>
|
||||
<property name="transition-duration">1000</property>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="swo">
|
||||
<property name="visible">True</property>
|
||||
<property name="shadow-type">none</property>
|
||||
<child>
|
||||
<object class="GtkTextView" id="tvo">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="buffer">textbuffer2</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">page1</property>
|
||||
<property name="icon-name">document-open-recent-symbolic</property>
|
||||
<property name="title">News</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage" id="imageo">
|
||||
<property name="visible">True</property>
|
||||
<property name="resource">/logos/gtk-logo-256.png</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">page2</property>
|
||||
<property name="icon-name">system-shutdown-symbolic</property>
|
||||
<property name="title">Logo</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
@@ -301,7 +301,7 @@ HTML_IMAGES = \
|
||||
$(srcdir)/images/appchooserdialog.png \
|
||||
$(srcdir)/images/assistant.png \
|
||||
$(srcdir)/images/box-packing.png \
|
||||
$(srcdir)/images/box-expand.png \
|
||||
$(srcdir)/images/box-expand.png \
|
||||
$(srcdir)/images/button.png \
|
||||
$(srcdir)/images/check-button.png \
|
||||
$(srcdir)/images/color-button.png \
|
||||
@@ -309,8 +309,8 @@ HTML_IMAGES = \
|
||||
$(srcdir)/images/colorchooser.png \
|
||||
$(srcdir)/images/combo-box.png \
|
||||
$(srcdir)/images/combo-box-entry.png \
|
||||
$(srcdir)/images/combo-box-text.png \
|
||||
$(srcdir)/images/entry.png \
|
||||
$(srcdir)/images/search-entry.png \
|
||||
$(srcdir)/images/figure-hierarchical-drawing.png \
|
||||
$(srcdir)/images/figure-windowed-label.png \
|
||||
$(srcdir)/images/file-button.png \
|
||||
@@ -321,6 +321,7 @@ HTML_IMAGES = \
|
||||
$(srcdir)/images/frame.png \
|
||||
$(srcdir)/images/icon-view.png \
|
||||
$(srcdir)/images/image.png \
|
||||
$(srcdir)/images/info-bar.png \
|
||||
$(srcdir)/images/label.png \
|
||||
$(srcdir)/images/levelbar.png \
|
||||
$(srcdir)/images/link-button.png \
|
||||
@@ -342,7 +343,9 @@ HTML_IMAGES = \
|
||||
$(srcdir)/images/radio-group.png \
|
||||
$(srcdir)/images/recentchooserdialog.png \
|
||||
$(srcdir)/images/scales.png \
|
||||
$(srcdir)/images/scrollbar.png \
|
||||
$(srcdir)/images/scrolledwindow.png \
|
||||
$(srcdir)/images/search-entry.png \
|
||||
$(srcdir)/images/separator.png \
|
||||
$(srcdir)/images/spinbutton.png \
|
||||
$(srcdir)/images/spinner.png \
|
||||
|
||||
@@ -42,7 +42,7 @@ feature of the shell. If you enclose a command in backticks
|
||||
substituted into the command line before execution. So to compile
|
||||
a GTK+ Hello, World, you would type the following:
|
||||
<programlisting>
|
||||
$ cc `pkg-config --cflags --libs gtk+-3.0` hello.c -o hello
|
||||
$ cc `pkg-config --cflags gtk+-3.0` hello.c -o hello `pkg-config --libs gtk+-3.0`
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
@@ -67,7 +67,7 @@ this range will trigger compiler warnings.
|
||||
Here is how you would compile hello.c if you want to allow it
|
||||
to use symbols that were not deprecated in 3.2:
|
||||
<programlisting>
|
||||
$ cc -DGDK_VERSION_MIN_REQUIRED=GDK_VERSION_3_2 `pkg-config --cflags --libs gtk+-3.0` hello.c -o hello
|
||||
$ cc `pkg-config --cflags gtk+-3.0` -DGDK_VERSION_MIN_REQIRED=GDK_VERSION_3_2 hello.c -o hello `pkg-config --libs gtk+-3.0`
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
@@ -75,7 +75,7 @@ $ cc -DGDK_VERSION_MIN_REQUIRED=GDK_VERSION_3_2 `pkg-config --cflags --libs gtk+
|
||||
And here is how you would compile hello.c if you don't want
|
||||
it to use any symbols that were introduced after 3.4:
|
||||
<programlisting>
|
||||
$ cc -DGDK_VERSION_MAX_ALLOWED=GDK_VERSION_3_4 `pkg-config --cflags --libs gtk+-3.0` hello.c -o hello
|
||||
$ cc `pkg-config --cflags gtk+-3.0` -DGDK_VERSION_MAX_ALLOWED=GDK_VERSION_3_4 hello.c -o hello `pkg-config --libs gtk+-3.0`
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
|
||||
@@ -237,6 +237,7 @@
|
||||
<xi:include href="xml/gtkstack.xml" />
|
||||
<xi:include href="xml/gtkstackswitcher.xml" />
|
||||
<xi:include href="xml/gtkexpander.xml" />
|
||||
<xi:include href="xml/gtkrevealer.xml" />
|
||||
<xi:include href="xml/gtkoverlay.xml" />
|
||||
<xi:include href="xml/gtkheaderbar.xml" />
|
||||
<xi:include href="xml/gtkorientable.xml" />
|
||||
|
||||
@@ -486,6 +486,8 @@ gtk_box_set_spacing
|
||||
gtk_box_reorder_child
|
||||
gtk_box_query_child_packing
|
||||
gtk_box_set_child_packing
|
||||
gtk_box_get_baseline_position
|
||||
gtk_box_set_baseline_position
|
||||
<SUBSECTION Standard>
|
||||
GTK_BOX
|
||||
GTK_IS_BOX
|
||||
@@ -2485,7 +2487,7 @@ gtk_paned_get_type
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkplacessidebar</FILE>
|
||||
<TITLE>GtkPlacesSidebar</FILE>
|
||||
<TITLE>GtkPlacesSidebar</TITLE>
|
||||
GtkPlacesSidebar
|
||||
GtkPlacesOpenFlags
|
||||
gtk_places_sidebar_new
|
||||
@@ -2493,11 +2495,14 @@ gtk_places_sidebar_set_open_flags
|
||||
gtk_places_sidebar_set_location
|
||||
gtk_places_sidebar_get_location
|
||||
gtk_places_sidebar_set_show_desktop
|
||||
gtk_places_sidebar_set_accept_uri_drops
|
||||
gtk_places_sidebar_add_shortcut
|
||||
gtk_places_sidebar_remove_shortcut
|
||||
gtk_places_sidebar_list_shortcuts
|
||||
gtk_places_sidebar_get_nth_bookmark
|
||||
gtk_places_sidebar_get_open_flags
|
||||
gtk_places_sidebar_get_show_connect_to_server
|
||||
gtk_places_sidebar_get_show_desktop
|
||||
gtk_places_sidebar_set_show_connect_to_server
|
||||
<SUBSECTION Standard>
|
||||
GTK_PLACES_SIDEBAR
|
||||
GTK_IS_PLACES_SIDEBAR
|
||||
@@ -5188,6 +5193,7 @@ gtk_widget_remove_tick_callback
|
||||
gtk_widget_size_request
|
||||
gtk_widget_get_child_requisition
|
||||
gtk_widget_size_allocate
|
||||
gtk_widget_size_allocate_with_baseline
|
||||
gtk_widget_add_accelerator
|
||||
gtk_widget_remove_accelerator
|
||||
gtk_widget_set_accel_path
|
||||
@@ -5320,6 +5326,7 @@ gtk_widget_get_allocated_width
|
||||
gtk_widget_get_allocated_height
|
||||
gtk_widget_get_allocation
|
||||
gtk_widget_set_allocation
|
||||
gtk_widget_get_allocated_baseline
|
||||
gtk_widget_get_app_paintable
|
||||
gtk_widget_get_can_default
|
||||
gtk_widget_set_can_default
|
||||
@@ -5380,8 +5387,10 @@ gtk_widget_get_preferred_height
|
||||
gtk_widget_get_preferred_width
|
||||
gtk_widget_get_preferred_height_for_width
|
||||
gtk_widget_get_preferred_width_for_height
|
||||
gtk_widget_get_preferred_height_and_baseline_for_width
|
||||
gtk_widget_get_request_mode
|
||||
gtk_widget_get_preferred_size
|
||||
gtk_widget_get_preferred_size_and_baseline
|
||||
gtk_distribute_natural_allocation
|
||||
|
||||
<SUBSECTION Alignment and Margins>
|
||||
@@ -5389,6 +5398,7 @@ GtkAlign
|
||||
gtk_widget_get_halign
|
||||
gtk_widget_set_halign
|
||||
gtk_widget_get_valign
|
||||
gtk_widget_get_valign_with_baseline
|
||||
gtk_widget_set_valign
|
||||
gtk_widget_get_margin_left
|
||||
gtk_widget_set_margin_left
|
||||
@@ -7290,6 +7300,10 @@ gtk_grid_set_column_homogeneous
|
||||
gtk_grid_get_column_homogeneous
|
||||
gtk_grid_set_column_spacing
|
||||
gtk_grid_get_column_spacing
|
||||
gtk_grid_get_baseline_row
|
||||
gtk_grid_set_baseline_row
|
||||
gtk_grid_get_row_baseline_position
|
||||
gtk_grid_set_row_baseline_position
|
||||
|
||||
<SUBSECTION Standard>
|
||||
GtkGridClass
|
||||
@@ -7594,3 +7608,18 @@ gtk_stack_switcher_new
|
||||
gtk_stack_switcher_set_stack
|
||||
gtk_stack_switcher_get_stack
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkrevealer</FILE>
|
||||
<TITLE>GtkRevealer</TITLE>
|
||||
GtkRevealer
|
||||
gtk_revealer_new
|
||||
gtk_revealer_get_reveal_child
|
||||
gtk_revealer_set_reveal_child
|
||||
gtk_revealer_get_child_revealed
|
||||
gtk_revealer_get_transition_duration
|
||||
gtk_revealer_set_transition_duration
|
||||
GtkRevealerTransitionType
|
||||
gtk_revealer_get_transition_type
|
||||
gtk_revealer_set_transition_type
|
||||
</SECTION>
|
||||
|
||||
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 7.8 KiB After Width: | Height: | Size: 8.0 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.7 KiB |
@@ -18,6 +18,9 @@
|
||||
<link linkend="GtkComboBox">
|
||||
<inlinegraphic fileref="combo-box.png" format="PNG"></inlinegraphic>
|
||||
</link>
|
||||
<link linkend="GtkComboBoxText">
|
||||
<inlinegraphic fileref="combo-box-text.png" format="PNG"></inlinegraphic>
|
||||
</link>
|
||||
<link linkend="GtkEntry">
|
||||
<inlinegraphic fileref="entry.png" format="PNG"></inlinegraphic>
|
||||
</link>
|
||||
@@ -147,4 +150,13 @@
|
||||
<link linkend="GtkFontChooserDialog">
|
||||
<inlinegraphic fileref="fontchooser.png" format="PNG"></inlinegraphic>
|
||||
</link>
|
||||
<link linkend="GtkAboutDialog">
|
||||
<inlinegraphic fileref="aboutdialog.png" format="PNG"></inlinegraphic>
|
||||
</link>
|
||||
<link linkend="GtkInfoBar">
|
||||
<inlinegraphic fileref="info-bar.png" format="PNG"></inlinegraphic>
|
||||
</link>
|
||||
<link linkend="GtkScrollbar">
|
||||
<inlinegraphic fileref="scrollbar.png" format="PNG"></inlinegraphic>
|
||||
</link>
|
||||
</para>
|
||||
|
||||
@@ -400,11 +400,6 @@ create_combo_box_entry (void)
|
||||
GtkWidget *align;
|
||||
GtkWidget *child;
|
||||
GtkTreeModel *model;
|
||||
|
||||
gtk_rc_parse_string ("style \"combo-box-entry-style\" {\n"
|
||||
" GtkComboBox::appears-as-list = 1\n"
|
||||
"}\n"
|
||||
"widget_class \"GtkComboBoxEntry\" style \"combo-box-entry-style\"\n" );
|
||||
|
||||
model = (GtkTreeModel *)gtk_list_store_new (1, G_TYPE_STRING);
|
||||
widget = g_object_new (GTK_TYPE_COMBO_BOX,
|
||||
@@ -427,14 +422,22 @@ create_combo_box (void)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
GtkWidget *align;
|
||||
|
||||
gtk_rc_parse_string ("style \"combo-box-style\" {\n"
|
||||
" GtkComboBox::appears-as-list = 0\n"
|
||||
"}\n"
|
||||
"widget_class \"GtkComboBox\" style \"combo-box-style\"\n" );
|
||||
GtkCellRenderer *cell;
|
||||
GtkListStore *store;
|
||||
|
||||
widget = gtk_combo_box_new ();
|
||||
gtk_cell_layout_clear (GTK_CELL_LAYOUT (widget));
|
||||
cell = gtk_cell_renderer_pixbuf_new ();
|
||||
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (widget), cell, FALSE);
|
||||
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (widget), cell, "icon-name", 0, NULL);
|
||||
cell = gtk_cell_renderer_text_new ();
|
||||
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (widget), cell, FALSE);
|
||||
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (widget), cell, "text", 1, NULL);
|
||||
|
||||
store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
|
||||
gtk_list_store_insert_with_values (store, NULL, -1, 0, "edit-delete", 1, "Combo Box", -1);
|
||||
gtk_combo_box_set_model (GTK_COMBO_BOX (widget), GTK_TREE_MODEL (store));
|
||||
|
||||
widget = gtk_combo_box_text_new ();
|
||||
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), "Combo Box");
|
||||
gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
|
||||
align = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
|
||||
gtk_container_add (GTK_CONTAINER (align), widget);
|
||||
@@ -442,6 +445,38 @@ create_combo_box (void)
|
||||
return new_widget_info ("combo-box", align, SMALL);
|
||||
}
|
||||
|
||||
static WidgetInfo *
|
||||
create_combo_box_text (void)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
GtkWidget *align;
|
||||
|
||||
widget = gtk_combo_box_text_new ();
|
||||
|
||||
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), "Combo Box Text");
|
||||
gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
|
||||
align = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
|
||||
gtk_container_add (GTK_CONTAINER (align), widget);
|
||||
|
||||
return new_widget_info ("combo-box-text", align, SMALL);
|
||||
}
|
||||
|
||||
static WidgetInfo *
|
||||
create_info_bar (void)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
GtkWidget *align;
|
||||
|
||||
widget = gtk_info_bar_new_with_buttons ("Close", 0, NULL);
|
||||
gtk_info_bar_set_message_type (GTK_INFO_BAR (widget), GTK_MESSAGE_INFO);
|
||||
gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_content_area (GTK_INFO_BAR (widget))),
|
||||
gtk_label_new ("Info Bar"));
|
||||
|
||||
align = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
|
||||
gtk_container_add (GTK_CONTAINER (align), widget);
|
||||
|
||||
return new_widget_info ("info-bar", align, SMALL);
|
||||
}
|
||||
static WidgetInfo *
|
||||
create_recent_chooser_dialog (void)
|
||||
{
|
||||
@@ -679,12 +714,12 @@ create_panes (void)
|
||||
pane = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);
|
||||
gtk_paned_pack1 (GTK_PANED (pane),
|
||||
g_object_new (GTK_TYPE_FRAME,
|
||||
"shadow", GTK_SHADOW_IN,
|
||||
"shadow-type", GTK_SHADOW_IN,
|
||||
NULL),
|
||||
FALSE, FALSE);
|
||||
gtk_paned_pack2 (GTK_PANED (pane),
|
||||
g_object_new (GTK_TYPE_FRAME,
|
||||
"shadow", GTK_SHADOW_IN,
|
||||
"shadow-type", GTK_SHADOW_IN,
|
||||
NULL),
|
||||
FALSE, FALSE);
|
||||
gtk_box_pack_start (GTK_BOX (hbox),
|
||||
@@ -693,12 +728,12 @@ create_panes (void)
|
||||
pane = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
|
||||
gtk_paned_pack1 (GTK_PANED (pane),
|
||||
g_object_new (GTK_TYPE_FRAME,
|
||||
"shadow", GTK_SHADOW_IN,
|
||||
"shadow-type", GTK_SHADOW_IN,
|
||||
NULL),
|
||||
FALSE, FALSE);
|
||||
gtk_paned_pack2 (GTK_PANED (pane),
|
||||
g_object_new (GTK_TYPE_FRAME,
|
||||
"shadow", GTK_SHADOW_IN,
|
||||
"shadow-type", GTK_SHADOW_IN,
|
||||
NULL),
|
||||
FALSE, FALSE);
|
||||
gtk_box_pack_start (GTK_BOX (hbox),
|
||||
@@ -1022,6 +1057,8 @@ create_scrolledwindow (void)
|
||||
GtkWidget *scrolledwin, *label;
|
||||
|
||||
scrolledwin = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwin),
|
||||
GTK_POLICY_ALWAYS, GTK_POLICY_ALWAYS);
|
||||
label = gtk_label_new ("Scrolled Window");
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (scrolledwin), label);
|
||||
@@ -1029,6 +1066,26 @@ create_scrolledwindow (void)
|
||||
return new_widget_info ("scrolledwindow", scrolledwin, MEDIUM);
|
||||
}
|
||||
|
||||
static WidgetInfo *
|
||||
create_scrollbar (void)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
GtkWidget *vbox, *align;
|
||||
|
||||
widget = gtk_scrollbar_new (GTK_ORIENTATION_HORIZONTAL, NULL);
|
||||
gtk_widget_set_size_request (widget, 100, -1);
|
||||
|
||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 3);
|
||||
align = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
|
||||
gtk_container_add (GTK_CONTAINER (align), widget);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), align, FALSE, FALSE, 0);
|
||||
gtk_box_pack_start (GTK_BOX (vbox),
|
||||
gtk_label_new ("Scrollbar"),
|
||||
FALSE, FALSE, 0);
|
||||
|
||||
return new_widget_info ("scrollbar", vbox, SMALL);
|
||||
}
|
||||
|
||||
static WidgetInfo *
|
||||
create_spinbutton (void)
|
||||
{
|
||||
@@ -1257,6 +1314,7 @@ get_all_widgets (void)
|
||||
retval = g_list_prepend (retval, create_color_button ());
|
||||
retval = g_list_prepend (retval, create_combo_box ());
|
||||
retval = g_list_prepend (retval, create_combo_box_entry ());
|
||||
retval = g_list_prepend (retval, create_combo_box_text ());
|
||||
retval = g_list_prepend (retval, create_entry ());
|
||||
retval = g_list_prepend (retval, create_file_button ());
|
||||
retval = g_list_prepend (retval, create_font_button ());
|
||||
@@ -1273,6 +1331,7 @@ get_all_widgets (void)
|
||||
retval = g_list_prepend (retval, create_radio ());
|
||||
retval = g_list_prepend (retval, create_scales ());
|
||||
retval = g_list_prepend (retval, create_scrolledwindow ());
|
||||
retval = g_list_prepend (retval, create_scrollbar ());
|
||||
retval = g_list_prepend (retval, create_separator ());
|
||||
retval = g_list_prepend (retval, create_spinbutton ());
|
||||
retval = g_list_prepend (retval, create_statusbar ());
|
||||
@@ -1298,6 +1357,7 @@ get_all_widgets (void)
|
||||
retval = g_list_prepend (retval, create_menu_button ());
|
||||
retval = g_list_prepend (retval, create_search_entry ());
|
||||
retval = g_list_prepend (retval, create_level_bar ());
|
||||
retval = g_list_prepend (retval, create_info_bar ());
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
@@ -174,6 +174,7 @@ libgdk_3_la_LIBADD += x11/libgdk-x11.la
|
||||
endif # USE_X11
|
||||
|
||||
if USE_QUARTZ
|
||||
libgdk_3_la_CFLAGS = -xobjective-c
|
||||
libgdk_3_la_LIBADD += quartz/libgdk-quartz.la
|
||||
endif # USE_QUARTZ
|
||||
|
||||
@@ -370,7 +371,7 @@ dist-hook: ../build/win32/vs9/gdk.vcproj ../build/win32/vs10/gdk.vcxproj ../buil
|
||||
done >libgdk.sourcefiles
|
||||
$(CPP) -P - <$(top_srcdir)/build/win32/vs9/gdk.vcprojin >$@
|
||||
rm libgdk.sourcefiles
|
||||
|
||||
|
||||
../build/win32/vs10/gdk.vcxproj: ../build/win32/vs10/gdk.vcxprojin
|
||||
for F in $(libgdk_3_la_SOURCES); do \
|
||||
case $$F in \
|
||||
|
||||
@@ -1470,56 +1470,6 @@ _gdk_broadway_window_queue_antiexpose (GdkWindow *window,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
copy_region (cairo_surface_t *surface,
|
||||
cairo_region_t *area,
|
||||
gint dx,
|
||||
gint dy)
|
||||
{
|
||||
cairo_t *cr;
|
||||
|
||||
cr = cairo_create (surface);
|
||||
|
||||
gdk_cairo_region (cr, area);
|
||||
cairo_clip (cr);
|
||||
|
||||
/* NB: This is a self-copy and Cairo doesn't support that yet.
|
||||
* So we do a litle trick.
|
||||
*/
|
||||
cairo_push_group (cr);
|
||||
|
||||
cairo_set_source_surface (cr, surface, dx, dy);
|
||||
cairo_paint (cr);
|
||||
|
||||
cairo_pop_group_to_source (cr);
|
||||
cairo_paint (cr);
|
||||
|
||||
cairo_destroy (cr);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_broadway_window_translate (GdkWindow *window,
|
||||
cairo_region_t *area,
|
||||
gint dx,
|
||||
gint dy)
|
||||
{
|
||||
GdkWindowImplBroadway *impl;
|
||||
GdkBroadwayDisplay *broadway_display;
|
||||
|
||||
impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
|
||||
|
||||
if (impl->surface)
|
||||
{
|
||||
copy_region (impl->surface, area, dx, dy);
|
||||
broadway_display = GDK_BROADWAY_DISPLAY (gdk_window_get_display (window));
|
||||
|
||||
if (_gdk_broadway_server_window_translate (broadway_display->server,
|
||||
impl->id,
|
||||
area, dx, dy))
|
||||
queue_flush (window);
|
||||
}
|
||||
}
|
||||
|
||||
guint32
|
||||
gdk_broadway_get_last_seen_time (GdkWindow *window)
|
||||
{
|
||||
@@ -1558,7 +1508,6 @@ gdk_window_impl_broadway_class_init (GdkWindowImplBroadwayClass *klass)
|
||||
impl_class->input_shape_combine_region = gdk_window_broadway_input_shape_combine_region;
|
||||
impl_class->set_static_gravities = gdk_window_broadway_set_static_gravities;
|
||||
impl_class->queue_antiexpose = _gdk_broadway_window_queue_antiexpose;
|
||||
impl_class->translate = _gdk_broadway_window_translate;
|
||||
impl_class->destroy = _gdk_broadway_window_destroy;
|
||||
impl_class->destroy_foreign = gdk_broadway_window_destroy_foreign;
|
||||
impl_class->resize_cairo_surface = gdk_window_broadway_resize_cairo_surface;
|
||||
|
||||
@@ -38,11 +38,12 @@
|
||||
#endif
|
||||
|
||||
#ifdef GDK_WINDOWING_QUARTZ
|
||||
/* We immediately include gdkquartzdisplaymanager.h here instead of
|
||||
* gdkquartz.h so that we do not have to enable -xobjective-c for the
|
||||
* "generic" GDK source code.
|
||||
/* When the gdk_quartz_display_open function is removed We can
|
||||
* immediately include gdkquartzdisplaymanager.h here instead of
|
||||
* gdkprivate-quartz.h so that we won't have to enable -xobjective-c
|
||||
* for the "generic" GDK source code.
|
||||
* #include "quartz/gdkquartzdisplaymanager.h"
|
||||
*/
|
||||
#include "quartz/gdkquartzdisplaymanager.h"
|
||||
#include "quartz/gdkprivate-quartz.h"
|
||||
#endif
|
||||
|
||||
@@ -309,7 +310,7 @@ struct _GdkBackend {
|
||||
GdkDisplay * (* open_display) (const char *name);
|
||||
};
|
||||
|
||||
GdkBackend gdk_backends[] = {
|
||||
static GdkBackend gdk_backends[] = {
|
||||
#ifdef GDK_WINDOWING_QUARTZ
|
||||
{ "quartz", gdk_quartz_display_manager_get_type, _gdk_quartz_display_open },
|
||||
#endif
|
||||
|
||||
@@ -384,6 +384,7 @@ gdk_frame_clock_paint_idle (void *data)
|
||||
case GDK_FRAME_CLOCK_PHASE_LAYOUT:
|
||||
if (priv->freeze_count == 0)
|
||||
{
|
||||
int iter;
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if ((_gdk_debug_flags & GDK_DEBUG_FRAMES) != 0)
|
||||
{
|
||||
@@ -394,11 +395,20 @@ gdk_frame_clock_paint_idle (void *data)
|
||||
#endif /* G_ENABLE_DEBUG */
|
||||
|
||||
priv->phase = GDK_FRAME_CLOCK_PHASE_LAYOUT;
|
||||
if (priv->requested & GDK_FRAME_CLOCK_PHASE_LAYOUT)
|
||||
/* We loop in the layout phase, because we don't want to progress
|
||||
* into the paint phase with invalid size allocations. This may
|
||||
* happen in some situation like races between user window
|
||||
* resizes and natural size changes.
|
||||
*/
|
||||
iter = 0;
|
||||
while ((priv->requested & GDK_FRAME_CLOCK_PHASE_LAYOUT) &&
|
||||
priv->freeze_count == 0 && iter++ < 4)
|
||||
{
|
||||
priv->requested &= ~GDK_FRAME_CLOCK_PHASE_LAYOUT;
|
||||
g_signal_emit_by_name (G_OBJECT (clock), "layout");
|
||||
}
|
||||
if (iter == 5)
|
||||
g_warning ("gdk-frame-clock: layout continuously requested, giving up after 4 tries");
|
||||
}
|
||||
case GDK_FRAME_CLOCK_PHASE_PAINT:
|
||||
if (priv->freeze_count == 0)
|
||||
|
||||
@@ -224,6 +224,7 @@ struct _GdkWindow
|
||||
guint native_visibility : 2; /* the native visibility of a impl windows */
|
||||
guint viewable : 1; /* mapped and all parents mapped */
|
||||
guint applied_shape : 1;
|
||||
guint in_update : 1;
|
||||
GdkFullscreenMode fullscreen_mode;
|
||||
|
||||
/* The GdkWindow that has the impl, ref:ed if another window.
|
||||
@@ -250,10 +251,6 @@ struct _GdkWindow
|
||||
GdkCursor *cursor;
|
||||
GHashTable *device_cursor;
|
||||
|
||||
GSList *implicit_paint;
|
||||
|
||||
GList *outstanding_moves;
|
||||
|
||||
cairo_region_t *shape;
|
||||
cairo_region_t *input_shape;
|
||||
|
||||
@@ -269,10 +266,11 @@ struct _GdkWindow
|
||||
guint num_offscreen_children;
|
||||
|
||||
GdkFrameClock *frame_clock; /* NULL to use from parent or default */
|
||||
GdkWindowInvalidateHandlerFunc invalidate_handler;
|
||||
};
|
||||
|
||||
#define GDK_WINDOW_TYPE(d) (((GDK_WINDOW (d)))->window_type)
|
||||
#define GDK_WINDOW_DESTROYED(d) (GDK_WINDOW (d)->destroyed)
|
||||
#define GDK_WINDOW_TYPE(d) ((((GdkWindow *)(d)))->window_type)
|
||||
#define GDK_WINDOW_DESTROYED(d) (((GdkWindow *)(d))->destroyed)
|
||||
|
||||
extern gchar *_gdk_display_name;
|
||||
extern gint _gdk_screen_number;
|
||||
@@ -354,26 +352,6 @@ void _gdk_windowing_got_event (GdkDisplay *display,
|
||||
|
||||
#define GDK_WINDOW_IS_MAPPED(window) (((window)->state & GDK_WINDOW_STATE_WITHDRAWN) == 0)
|
||||
|
||||
#define GDK_TYPE_PAINTABLE (_gdk_paintable_get_type ())
|
||||
#define GDK_PAINTABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_PAINTABLE, GdkPaintable))
|
||||
#define GDK_IS_PAINTABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_PAINTABLE))
|
||||
#define GDK_PAINTABLE_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GDK_TYPE_PAINTABLE, GdkPaintableIface))
|
||||
|
||||
typedef struct _GdkPaintable GdkPaintable;
|
||||
typedef struct _GdkPaintableIface GdkPaintableIface;
|
||||
|
||||
struct _GdkPaintableIface
|
||||
{
|
||||
GTypeInterface g_iface;
|
||||
|
||||
void (* begin_paint_region) (GdkPaintable *paintable,
|
||||
GdkWindow *window,
|
||||
const cairo_region_t *region);
|
||||
void (* end_paint) (GdkPaintable *paintable);
|
||||
};
|
||||
|
||||
GType _gdk_paintable_get_type (void) G_GNUC_CONST;
|
||||
|
||||
void _gdk_window_invalidate_for_expose (GdkWindow *window,
|
||||
cairo_region_t *region);
|
||||
|
||||
|
||||
@@ -555,42 +555,6 @@ gdk_offscreen_window_queue_antiexpose (GdkWindow *window,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_offscreen_window_translate (GdkWindow *window,
|
||||
cairo_region_t *area,
|
||||
gint dx,
|
||||
gint dy)
|
||||
{
|
||||
GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (window->impl);
|
||||
|
||||
if (offscreen->surface)
|
||||
{
|
||||
cairo_t *cr;
|
||||
|
||||
cr = cairo_create (offscreen->surface);
|
||||
|
||||
area = cairo_region_copy (area);
|
||||
|
||||
gdk_cairo_region (cr, area);
|
||||
cairo_clip (cr);
|
||||
|
||||
/* NB: This is a self-copy and Cairo doesn't support that yet.
|
||||
* So we do a litle trick.
|
||||
*/
|
||||
cairo_push_group (cr);
|
||||
|
||||
cairo_set_source_surface (cr, offscreen->surface, dx, dy);
|
||||
cairo_paint (cr);
|
||||
|
||||
cairo_pop_group_to_source (cr);
|
||||
cairo_paint (cr);
|
||||
|
||||
cairo_destroy (cr);
|
||||
}
|
||||
|
||||
_gdk_window_add_damage (window, area);
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
gdk_offscreen_window_resize_cairo_surface (GdkWindow *window,
|
||||
cairo_surface_t *surface,
|
||||
@@ -752,7 +716,6 @@ gdk_offscreen_window_class_init (GdkOffscreenWindowClass *klass)
|
||||
impl_class->input_shape_combine_region = gdk_offscreen_window_input_shape_combine_region;
|
||||
impl_class->set_static_gravities = gdk_offscreen_window_set_static_gravities;
|
||||
impl_class->queue_antiexpose = gdk_offscreen_window_queue_antiexpose;
|
||||
impl_class->translate = gdk_offscreen_window_translate;
|
||||
impl_class->destroy = gdk_offscreen_window_destroy;
|
||||
impl_class->destroy_foreign = NULL;
|
||||
impl_class->resize_cairo_surface = gdk_offscreen_window_resize_cairo_surface;
|
||||
|
||||
@@ -634,6 +634,26 @@ gboolean gdk_window_set_static_gravities (GdkWindow *window,
|
||||
|
||||
/* GdkWindow */
|
||||
|
||||
/**
|
||||
* GdkWindowInvalidateHandlerFunc:
|
||||
* @window: a #GdkWindow
|
||||
* @region: a #cairo_region_t
|
||||
*
|
||||
* Whenever some area of the window is invalidated (directly in the
|
||||
* window or in a child window) this gets called with @region in
|
||||
* the coordinate space of @window. You can use @region to just
|
||||
* keep track of the dirty region, or you can actually change
|
||||
* @region in case you are doing display tricks like showing
|
||||
* a child in multiple places.
|
||||
*
|
||||
* Since: 3.10
|
||||
*/
|
||||
typedef void (*GdkWindowInvalidateHandlerFunc) (GdkWindow *window,
|
||||
cairo_region_t *region);
|
||||
GDK_AVAILABLE_IN_3_10
|
||||
void gdk_window_set_invalidate_handler (GdkWindow *window,
|
||||
GdkWindowInvalidateHandlerFunc handler);
|
||||
|
||||
gboolean gdk_window_has_native (GdkWindow *window);
|
||||
void gdk_window_set_type_hint (GdkWindow *window,
|
||||
GdkWindowTypeHint hint);
|
||||
@@ -747,6 +767,9 @@ GdkWindow * gdk_window_get_effective_toplevel (GdkWindow *window);
|
||||
|
||||
GList * gdk_window_get_children (GdkWindow *window);
|
||||
GList * gdk_window_peek_children (GdkWindow *window);
|
||||
GList * gdk_window_get_children_with_user_data (GdkWindow *window,
|
||||
gpointer user_data);
|
||||
|
||||
GdkEventMask gdk_window_get_events (GdkWindow *window);
|
||||
void gdk_window_set_events (GdkWindow *window,
|
||||
GdkEventMask event_mask);
|
||||
|
||||
@@ -101,6 +101,9 @@ struct _GdkWindowImplClass
|
||||
gint *x,
|
||||
gint *y,
|
||||
GdkModifierType *mask);
|
||||
gboolean (* begin_paint_region) (GdkWindow *window,
|
||||
const cairo_region_t *region);
|
||||
void (* end_paint) (GdkWindow *window);
|
||||
|
||||
cairo_region_t * (* get_shape) (GdkWindow *window);
|
||||
cairo_region_t * (* get_input_shape) (GdkWindow *window);
|
||||
@@ -125,16 +128,6 @@ struct _GdkWindowImplClass
|
||||
gboolean (* queue_antiexpose) (GdkWindow *window,
|
||||
cairo_region_t *update_area);
|
||||
|
||||
/* Called to move @area inside @window by @dx x @dy pixels. @area is
|
||||
* guaranteed to be inside @window. If part of @area is not invisible or
|
||||
* invalid, it is this function's job to queue expose events in those
|
||||
* areas.
|
||||
*/
|
||||
void (* translate) (GdkWindow *window,
|
||||
cairo_region_t *area,
|
||||
gint dx,
|
||||
gint dy);
|
||||
|
||||
/* Called to do the windowing system specific part of gdk_window_destroy(),
|
||||
*
|
||||
* window: The window being destroyed
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#define __GDK_QUARTZ_DEVICE_MANAGER_CORE__
|
||||
|
||||
#include <gdkdevicemanagerprivate.h>
|
||||
#include <gdkquartzdevicemanager-core.h>
|
||||
#include "gdkquartzdevicemanager-core.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
@@ -71,7 +71,4 @@ gdk_quartz_display_manager_class_init (GdkQuartzDisplayManagerClass *class)
|
||||
GdkDisplayManagerClass *manager_class = GDK_DISPLAY_MANAGER_CLASS (class);
|
||||
|
||||
object_class->finalize = gdk_quartz_display_manager_finalize;
|
||||
|
||||
manager_class->atom_intern = _gdk_quartz_display_manager_atom_intern;
|
||||
manager_class->get_atom_name = _gdk_quartz_display_manager_get_atom_name;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#define __GDK_QUARTZ_DND__
|
||||
|
||||
#include <gdkdndprivate.h>
|
||||
#include <gdkquartzdnd.h>
|
||||
#include "gdkquartzdnd.h"
|
||||
|
||||
#include <AppKit/AppKit.h>
|
||||
|
||||
|
||||
@@ -154,14 +154,6 @@ gint _gdk_quartz_display_text_property_to_utf8_list (GdkDisplay *disp
|
||||
gchar * _gdk_quartz_display_utf8_to_string_target (GdkDisplay *displayt,
|
||||
const gchar *str);
|
||||
|
||||
|
||||
/* Display manager methods - events */
|
||||
GdkAtom _gdk_quartz_display_manager_atom_intern (GdkDisplayManager *manager,
|
||||
const gchar *atom_name,
|
||||
gboolean copy_name);
|
||||
gchar * _gdk_quartz_display_manager_get_atom_name (GdkDisplayManager *manager,
|
||||
GdkAtom atom);
|
||||
|
||||
/* Screen */
|
||||
GdkScreen *_gdk_quartz_screen_new (void);
|
||||
void _gdk_quartz_screen_update_window_sizes (GdkScreen *screen);
|
||||
|
||||
@@ -148,26 +148,6 @@ intern_atom_internal (const gchar *atom_name, gboolean allocate)
|
||||
return result;
|
||||
}
|
||||
|
||||
GdkAtom
|
||||
_gdk_quartz_display_manager_atom_intern (GdkDisplayManager *manager,
|
||||
const gchar *atom_name,
|
||||
gboolean copy_name)
|
||||
{
|
||||
return intern_atom_internal (atom_name, copy_name);
|
||||
}
|
||||
|
||||
gchar *
|
||||
_gdk_quartz_display_manager_get_atom_name (GdkDisplayManager *manager,
|
||||
GdkAtom atom)
|
||||
{
|
||||
ensure_atom_tables ();
|
||||
|
||||
if (GPOINTER_TO_INT (atom) >= atoms_to_names->len)
|
||||
return NULL;
|
||||
|
||||
return g_strdup (g_ptr_array_index (atoms_to_names, GPOINTER_TO_INT (atom)));
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_quartz_window_delete_property (GdkWindow *window,
|
||||
GdkAtom property)
|
||||
|
||||
@@ -364,19 +364,18 @@ gdk_window_impl_quartz_init (GdkWindowImplQuartz *impl)
|
||||
impl->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_window_impl_quartz_begin_paint_region (GdkPaintable *paintable,
|
||||
GdkWindow *window,
|
||||
static gboolean
|
||||
gdk_window_impl_quartz_begin_paint_region (GdkWindow *window,
|
||||
const cairo_region_t *region)
|
||||
{
|
||||
GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (paintable);
|
||||
GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (window->imp);
|
||||
cairo_region_t *clipped_and_offset_region;
|
||||
cairo_t *cr;
|
||||
|
||||
clipped_and_offset_region = cairo_region_copy (region);
|
||||
|
||||
cairo_region_intersect (clipped_and_offset_region,
|
||||
window->clip_region_with_children);
|
||||
window->clip_region);
|
||||
cairo_region_translate (clipped_and_offset_region,
|
||||
window->abs_x, window->abs_y);
|
||||
|
||||
@@ -415,12 +414,14 @@ gdk_window_impl_quartz_begin_paint_region (GdkPaintable *paintable,
|
||||
|
||||
done:
|
||||
cairo_region_destroy (clipped_and_offset_region);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_window_impl_quartz_end_paint (GdkPaintable *paintable)
|
||||
gdk_window_impl_quartz_end_paint (GdkWindow *window)
|
||||
{
|
||||
GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (paintable);
|
||||
GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
|
||||
|
||||
impl->begin_paint_count--;
|
||||
|
||||
@@ -536,13 +537,6 @@ _gdk_quartz_display_after_process_all_updates (GdkDisplay *display)
|
||||
NSEnableScreenUpdates ();
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_window_impl_quartz_paintable_init (GdkPaintableIface *iface)
|
||||
{
|
||||
iface->begin_paint_region = gdk_window_impl_quartz_begin_paint_region;
|
||||
iface->end_paint = gdk_window_impl_quartz_end_paint;
|
||||
}
|
||||
|
||||
static const gchar *
|
||||
get_default_title (void)
|
||||
{
|
||||
@@ -2237,49 +2231,6 @@ gdk_quartz_window_queue_antiexpose (GdkWindow *window,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_window_translate (GdkWindow *window,
|
||||
cairo_region_t *area,
|
||||
gint dx,
|
||||
gint dy)
|
||||
{
|
||||
cairo_region_t *invalidate, *scrolled;
|
||||
GdkWindowImplQuartz *impl = (GdkWindowImplQuartz *)window->impl;
|
||||
GdkRectangle extents;
|
||||
|
||||
cairo_region_get_extents (area, &extents);
|
||||
|
||||
[impl->view scrollRect:NSMakeRect (extents.x - dx, extents.y - dy,
|
||||
extents.width, extents.height)
|
||||
by:NSMakeSize (dx, dy)];
|
||||
|
||||
if (impl->needs_display_region)
|
||||
{
|
||||
cairo_region_t *intersection;
|
||||
|
||||
/* Invalidate already invalidated area that was moved at new
|
||||
* location.
|
||||
*/
|
||||
intersection = cairo_region_copy (impl->needs_display_region);
|
||||
cairo_region_intersect (intersection, area);
|
||||
cairo_region_translate (intersection, dx, dy);
|
||||
|
||||
gdk_quartz_window_set_needs_display_in_region (window, intersection);
|
||||
cairo_region_destroy (intersection);
|
||||
}
|
||||
|
||||
/* Calculate newly exposed area that needs invalidation */
|
||||
scrolled = cairo_region_copy (area);
|
||||
cairo_region_translate (scrolled, dx, dy);
|
||||
|
||||
invalidate = cairo_region_copy (area);
|
||||
cairo_region_subtract (invalidate, scrolled);
|
||||
cairo_region_destroy (scrolled);
|
||||
|
||||
gdk_quartz_window_set_needs_display_in_region (window, invalidate);
|
||||
cairo_region_destroy (invalidate);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_window_set_focus_on_map (GdkWindow *window,
|
||||
gboolean focus_on_map)
|
||||
@@ -3078,12 +3029,13 @@ gdk_window_impl_quartz_class_init (GdkWindowImplQuartzClass *klass)
|
||||
impl_class->input_shape_combine_region = gdk_window_quartz_input_shape_combine_region;
|
||||
impl_class->set_static_gravities = gdk_window_quartz_set_static_gravities;
|
||||
impl_class->queue_antiexpose = gdk_quartz_window_queue_antiexpose;
|
||||
impl_class->translate = gdk_quartz_window_translate;
|
||||
impl_class->destroy = gdk_quartz_window_destroy;
|
||||
impl_class->destroy_foreign = gdk_quartz_window_destroy_foreign;
|
||||
impl_class->resize_cairo_surface = gdk_window_quartz_resize_cairo_surface;
|
||||
impl_class->get_shape = gdk_quartz_window_get_shape;
|
||||
impl_class->get_input_shape = gdk_quartz_window_get_input_shape;
|
||||
impl_class->begin_paint_region = gdk_window_impl_quartz_begin_paint_region;
|
||||
impl_class->end_paint = gdk_window_impl_quartz_end_paint;
|
||||
|
||||
impl_class->focus = gdk_quartz_window_focus;
|
||||
impl_class->set_type_hint = gdk_quartz_window_set_type_hint;
|
||||
@@ -3159,19 +3111,9 @@ _gdk_window_impl_quartz_get_type (void)
|
||||
(GInstanceInitFunc) gdk_window_impl_quartz_init,
|
||||
};
|
||||
|
||||
const GInterfaceInfo paintable_info =
|
||||
{
|
||||
(GInterfaceInitFunc) gdk_window_impl_quartz_paintable_init,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
object_type = g_type_register_static (GDK_TYPE_WINDOW_IMPL,
|
||||
"GdkWindowImplQuartz",
|
||||
&object_info, 0);
|
||||
g_type_add_interface_static (object_type,
|
||||
GDK_TYPE_PAINTABLE,
|
||||
&paintable_info);
|
||||
}
|
||||
|
||||
return object_type;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
static void
|
||||
test_unset_display (void)
|
||||
{
|
||||
if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT | G_TEST_TRAP_SILENCE_STDERR))
|
||||
if (g_test_trap_fork (0, 0))//G_TEST_TRAP_SILENCE_STDOUT | G_TEST_TRAP_SILENCE_STDERR))
|
||||
{
|
||||
GdkDisplayManager *manager;
|
||||
|
||||
|
||||
@@ -260,8 +260,6 @@ gdk_wayland_display_dispose (GObject *object)
|
||||
{
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (object);
|
||||
|
||||
_gdk_wayland_display_manager_remove_display (gdk_display_manager_get (),
|
||||
GDK_DISPLAY (display_wayland));
|
||||
g_list_foreach (display_wayland->input_devices,
|
||||
(GFunc) g_object_run_dispose, NULL);
|
||||
|
||||
@@ -613,9 +611,6 @@ gdk_wayland_display_class_init (GdkWaylandDisplayClass * class)
|
||||
static void
|
||||
gdk_wayland_display_init (GdkWaylandDisplay *display)
|
||||
{
|
||||
_gdk_wayland_display_manager_add_display (gdk_display_manager_get (),
|
||||
GDK_DISPLAY (display));
|
||||
|
||||
display->xkb_context = xkb_context_new (0);
|
||||
}
|
||||
|
||||
|
||||
@@ -101,31 +101,3 @@ gdk_wayland_display_manager_init (GdkWaylandDisplayManager *manager)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_wayland_display_manager_add_display (GdkDisplayManager *manager,
|
||||
GdkDisplay *display)
|
||||
{
|
||||
GdkWaylandDisplayManager *manager_wayland = GDK_WAYLAND_DISPLAY_MANAGER (manager);
|
||||
|
||||
if (manager_wayland->displays == NULL)
|
||||
gdk_display_manager_set_default_display (manager, display);
|
||||
|
||||
manager_wayland->displays = g_slist_prepend (manager_wayland->displays, display);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_wayland_display_manager_remove_display (GdkDisplayManager *manager,
|
||||
GdkDisplay *display)
|
||||
{
|
||||
GdkWaylandDisplayManager *manager_wayland = GDK_WAYLAND_DISPLAY_MANAGER (manager);
|
||||
|
||||
manager_wayland->displays = g_slist_remove (manager_wayland->displays, display);
|
||||
|
||||
if (gdk_display_manager_get_default_display (manager) == display)
|
||||
{
|
||||
if (manager_wayland->displays)
|
||||
gdk_display_manager_set_default_display (manager, manager_wayland->displays->data);
|
||||
else
|
||||
gdk_display_manager_set_default_display (manager, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,11 +164,8 @@ void _gdk_wayland_screen_add_output (GdkScreen *screen,
|
||||
struct wl_output *output);
|
||||
void _gdk_wayland_screen_remove_output (GdkScreen *screen,
|
||||
guint32 id);
|
||||
|
||||
void _gdk_wayland_display_manager_add_display (GdkDisplayManager *manager,
|
||||
GdkDisplay *display);
|
||||
void _gdk_wayland_display_manager_remove_display (GdkDisplayManager *manager,
|
||||
GdkDisplay *display);
|
||||
int _gdk_wayland_screen_get_output_refresh_rate (GdkScreen *screen,
|
||||
struct wl_output *output);
|
||||
|
||||
void _gdk_wayland_window_set_device_grabbed (GdkWindow *window,
|
||||
GdkDevice *device,
|
||||
|
||||
@@ -87,6 +87,7 @@ struct _GdkWaylandMonitor
|
||||
int height_mm;
|
||||
char * output_name;
|
||||
char * manufacturer;
|
||||
int refresh_rate;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GdkWaylandScreen, _gdk_wayland_screen, GDK_TYPE_SCREEN)
|
||||
@@ -130,7 +131,7 @@ gdk_wayland_screen_dispose (GObject *object)
|
||||
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (object);
|
||||
|
||||
if (screen_wayland->root_window)
|
||||
_gdk_window_destroy (screen_wayland->root_window, TRUE);
|
||||
_gdk_window_destroy (screen_wayland->root_window, FALSE);
|
||||
|
||||
G_OBJECT_CLASS (_gdk_wayland_screen_parent_class)->dispose (object);
|
||||
}
|
||||
@@ -917,6 +918,7 @@ output_handle_mode(void *data,
|
||||
|
||||
monitor->geometry.width = width;
|
||||
monitor->geometry.height = height;
|
||||
monitor->refresh_rate = refresh;
|
||||
|
||||
g_signal_emit_by_name (monitor->screen, "monitors-changed");
|
||||
update_screen_size (monitor->screen);
|
||||
@@ -965,3 +967,21 @@ _gdk_wayland_screen_remove_output (GdkScreen *screen,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
_gdk_wayland_screen_get_output_refresh_rate (GdkScreen *screen,
|
||||
struct wl_output *output)
|
||||
{
|
||||
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < screen_wayland->monitors->len; i++)
|
||||
{
|
||||
GdkWaylandMonitor *monitor = screen_wayland->monitors->pdata[i];
|
||||
|
||||
if (monitor->output == output)
|
||||
return monitor->refresh_rate;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "gdkwindow.h"
|
||||
#include "gdkwindowimpl.h"
|
||||
#include "gdkdisplay-wayland.h"
|
||||
#include "gdkframeclockprivate.h"
|
||||
#include "gdkprivate-wayland.h"
|
||||
#include "gdkinternals.h"
|
||||
#include "gdkdeviceprivate.h"
|
||||
@@ -95,6 +96,9 @@ struct _GdkWindowImplWayland
|
||||
|
||||
GdkCursor *cursor;
|
||||
|
||||
/* The wl_outputs that this window currently touches */
|
||||
GSList *outputs;
|
||||
|
||||
struct wl_surface *surface;
|
||||
struct wl_shell_surface *shell_surface;
|
||||
unsigned int mapped : 1;
|
||||
@@ -140,6 +144,9 @@ struct _GdkWindowImplWayland
|
||||
} saved_fullscreen, saved_maximized;
|
||||
|
||||
gboolean use_custom_surface;
|
||||
|
||||
gboolean pending_commit;
|
||||
gint64 pending_frame_counter;
|
||||
};
|
||||
|
||||
struct _GdkWindowImplWaylandClass
|
||||
@@ -256,6 +263,162 @@ get_default_title (void)
|
||||
return title;
|
||||
}
|
||||
|
||||
static void
|
||||
fill_presentation_time_from_frame_time (GdkFrameTimings *timings,
|
||||
guint32 frame_time)
|
||||
{
|
||||
/* The timestamp in a wayland frame is a msec time value that in some
|
||||
* way reflects the time at which the server started drawing the frame.
|
||||
* This is not useful from our perspective.
|
||||
*
|
||||
* However, for the DRM backend of Weston, on reasonably recent
|
||||
* Linux, we know that the time is the
|
||||
* clock_gettime(CLOCK_MONOTONIC) value at the vblank, and that
|
||||
* backend starts drawing immediately after receiving the vblank
|
||||
* notification. If we detect this, and make the assumption that the
|
||||
* compositor will finish drawing before the next vblank, we can
|
||||
* then determine the presentation time as the frame time we
|
||||
* recieved plus one refresh interval.
|
||||
*
|
||||
* If a backend is using clock_gettime(CLOCK_MONOTONIC), but not
|
||||
* picking values right at the vblank, then the presentation times
|
||||
* we compute won't be accurate, but not really worse than then
|
||||
* the alternative of not providing presentation times at all.
|
||||
*
|
||||
* The complexity here is dealing with the fact that we receive
|
||||
* only the low 32 bits of the CLOCK_MONOTONIC value in milliseconds.
|
||||
*/
|
||||
gint64 now_monotonic = g_get_monotonic_time ();
|
||||
gint64 now_monotonic_msec = now_monotonic / 1000;
|
||||
uint32_t now_monotonic_low = (uint32_t)now_monotonic_msec;
|
||||
|
||||
if (frame_time - now_monotonic_low < 1000 ||
|
||||
frame_time - now_monotonic_low > (uint32_t)-1000)
|
||||
{
|
||||
/* Timestamp we received is within one second of the current time.
|
||||
*/
|
||||
gint64 last_frame_time = now_monotonic + (gint64)1000 * (gint32)(frame_time - now_monotonic_low);
|
||||
if ((gint32)now_monotonic_low < 0 && (gint32)frame_time > 0)
|
||||
last_frame_time += (gint64)1000 * G_GINT64_CONSTANT(0x100000000);
|
||||
else if ((gint32)now_monotonic_low > 0 && (gint32)frame_time < 0)
|
||||
last_frame_time -= (gint64)1000 * G_GINT64_CONSTANT(0x100000000);
|
||||
|
||||
timings->presentation_time = last_frame_time + timings->refresh_interval;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
frame_callback (void *data,
|
||||
struct wl_callback *callback,
|
||||
uint32_t time)
|
||||
{
|
||||
GdkWindow *window = data;
|
||||
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
||||
GdkWaylandDisplay *wayland_display = GDK_WAYLAND_DISPLAY (gdk_window_get_display (window));
|
||||
GdkFrameClock *clock = gdk_window_get_frame_clock (window);
|
||||
GdkFrameTimings *timings;
|
||||
|
||||
wl_callback_destroy (callback);
|
||||
_gdk_frame_clock_thaw (clock);
|
||||
|
||||
timings = gdk_frame_clock_get_timings (clock, impl->pending_frame_counter);
|
||||
impl->pending_frame_counter = 0;
|
||||
|
||||
if (timings == NULL)
|
||||
return;
|
||||
|
||||
timings->refresh_interval = 16667; /* default to 1/60th of a second */
|
||||
if (impl->outputs)
|
||||
{
|
||||
/* We pick a random output out of the outputs that the window touches
|
||||
* The rate here is in milli-hertz */
|
||||
int refresh_rate = _gdk_wayland_screen_get_output_refresh_rate (wayland_display->screen,
|
||||
impl->outputs->data);
|
||||
if (refresh_rate != 0)
|
||||
timings->refresh_interval = G_GINT64_CONSTANT(1000000000) / refresh_rate;
|
||||
}
|
||||
|
||||
fill_presentation_time_from_frame_time (timings, time);
|
||||
|
||||
timings->complete = TRUE;
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if ((_gdk_debug_flags & GDK_DEBUG_FRAMES) != 0)
|
||||
_gdk_frame_clock_debug_print_timings (clock, timings);
|
||||
#endif
|
||||
}
|
||||
|
||||
static const struct wl_callback_listener listener = {
|
||||
frame_callback
|
||||
};
|
||||
|
||||
static void
|
||||
on_frame_clock_before_paint (GdkFrameClock *clock,
|
||||
GdkWindow *window)
|
||||
{
|
||||
GdkFrameTimings *timings = gdk_frame_clock_get_current_timings (clock);
|
||||
gint64 presentation_time;
|
||||
gint64 refresh_interval;
|
||||
|
||||
gdk_frame_clock_get_refresh_info (clock,
|
||||
timings->frame_time,
|
||||
&refresh_interval, &presentation_time);
|
||||
|
||||
if (presentation_time != 0)
|
||||
{
|
||||
/* Assume the algorithm used by the DRM backend of Weston - it
|
||||
* starts drawing at the next vblank after receiving the commit
|
||||
* for this frame, and presentation occurs at the vblank
|
||||
* after that.
|
||||
*/
|
||||
timings->predicted_presentation_time = presentation_time + refresh_interval;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* As above, but we don't actually know the phase of the vblank,
|
||||
* so just assume that we're half way through a refresh cycle.
|
||||
*/
|
||||
timings->predicted_presentation_time = timings->frame_time + refresh_interval / 2 + refresh_interval;
|
||||
}
|
||||
}
|
||||
|
||||
static const cairo_user_data_key_t gdk_wayland_cairo_key;
|
||||
|
||||
typedef struct _GdkWaylandCairoSurfaceData {
|
||||
gpointer buf;
|
||||
size_t buf_length;
|
||||
struct wl_shm_pool *pool;
|
||||
struct wl_buffer *buffer;
|
||||
GdkWaylandDisplay *display;
|
||||
int32_t width, height;
|
||||
gboolean busy;
|
||||
} GdkWaylandCairoSurfaceData;
|
||||
|
||||
static void
|
||||
on_frame_clock_after_paint (GdkFrameClock *clock,
|
||||
GdkWindow *window)
|
||||
{
|
||||
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
||||
GdkWaylandCairoSurfaceData *data;
|
||||
struct wl_callback *callback;
|
||||
|
||||
if (!impl->pending_commit)
|
||||
return;
|
||||
|
||||
impl->pending_commit = FALSE;
|
||||
impl->pending_frame_counter = gdk_frame_clock_get_frame_counter (clock);
|
||||
|
||||
callback = wl_surface_frame (impl->surface);
|
||||
wl_callback_add_listener (callback, &listener, window);
|
||||
_gdk_frame_clock_freeze (clock);
|
||||
|
||||
wl_surface_commit (impl->surface);
|
||||
|
||||
data = cairo_surface_get_user_data (impl->cairo_surface,
|
||||
&gdk_wayland_cairo_key);
|
||||
data->busy = TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_wayland_display_create_window_impl (GdkDisplay *display,
|
||||
GdkWindow *window,
|
||||
@@ -266,6 +429,7 @@ _gdk_wayland_display_create_window_impl (GdkDisplay *display,
|
||||
gint attributes_mask)
|
||||
{
|
||||
GdkWindowImplWayland *impl;
|
||||
GdkFrameClock *frame_clock;
|
||||
const char *title;
|
||||
|
||||
impl = g_object_new (GDK_TYPE_WINDOW_IMPL_WAYLAND, NULL);
|
||||
@@ -306,19 +470,15 @@ _gdk_wayland_display_create_window_impl (GdkDisplay *display,
|
||||
|
||||
if (attributes_mask & GDK_WA_TYPE_HINT)
|
||||
gdk_window_set_type_hint (window, attributes->type_hint);
|
||||
|
||||
frame_clock = gdk_window_get_frame_clock (window);
|
||||
|
||||
g_signal_connect (frame_clock, "before-paint",
|
||||
G_CALLBACK (on_frame_clock_before_paint), window);
|
||||
g_signal_connect (frame_clock, "after-paint",
|
||||
G_CALLBACK (on_frame_clock_after_paint), window);
|
||||
}
|
||||
|
||||
static const cairo_user_data_key_t gdk_wayland_cairo_key;
|
||||
|
||||
typedef struct _GdkWaylandCairoSurfaceData {
|
||||
gpointer buf;
|
||||
size_t buf_length;
|
||||
struct wl_shm_pool *pool;
|
||||
struct wl_buffer *buffer;
|
||||
GdkWaylandDisplay *display;
|
||||
int32_t width, height;
|
||||
} GdkWaylandCairoSurfaceData;
|
||||
|
||||
static void
|
||||
gdk_wayland_window_attach_image (GdkWindow *window)
|
||||
{
|
||||
@@ -368,6 +528,7 @@ gdk_wayland_window_attach_image (GdkWindow *window)
|
||||
|
||||
/* Attach this new buffer to the surface */
|
||||
wl_surface_attach (impl->surface, data->buffer, dx, dy);
|
||||
impl->pending_commit = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -433,6 +594,19 @@ _create_shm_pool (struct wl_shm *shm,
|
||||
return pool;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
buffer_release_callback (void *_data, struct wl_buffer *wl_buffer)
|
||||
{
|
||||
GdkWaylandCairoSurfaceData *data = _data;
|
||||
|
||||
data->busy = FALSE;
|
||||
}
|
||||
|
||||
static const struct wl_buffer_listener buffer_listener = {
|
||||
buffer_release_callback
|
||||
};
|
||||
|
||||
static cairo_surface_t *
|
||||
gdk_wayland_create_cairo_surface (GdkWaylandDisplay *display,
|
||||
int width, int height)
|
||||
@@ -447,6 +621,7 @@ gdk_wayland_create_cairo_surface (GdkWaylandDisplay *display,
|
||||
data->buffer = NULL;
|
||||
data->width = width;
|
||||
data->height = height;
|
||||
data->busy = FALSE;
|
||||
|
||||
stride = width * 4;
|
||||
|
||||
@@ -458,6 +633,7 @@ gdk_wayland_create_cairo_surface (GdkWaylandDisplay *display,
|
||||
data->buffer = wl_shm_pool_create_buffer (data->pool, 0,
|
||||
width, height,
|
||||
stride, WL_SHM_FORMAT_ARGB8888);
|
||||
wl_buffer_add_listener (data->buffer, &buffer_listener, data);
|
||||
|
||||
surface = cairo_image_surface_create_for_data (data->buf,
|
||||
CAIRO_FORMAT_ARGB32,
|
||||
@@ -478,28 +654,34 @@ gdk_wayland_create_cairo_surface (GdkWaylandDisplay *display,
|
||||
return surface;
|
||||
}
|
||||
|
||||
/* On this first call this creates a double reference - the first reference
|
||||
* is held by the GdkWindowImplWayland struct - since unlike other backends
|
||||
* the Cairo surface is not just a cheap wrapper around some other backing.
|
||||
* It is the buffer itself.
|
||||
*/
|
||||
static cairo_surface_t *
|
||||
gdk_wayland_window_ref_cairo_surface (GdkWindow *window)
|
||||
static void
|
||||
gdk_wayland_window_ensure_cairo_surface (GdkWindow *window)
|
||||
{
|
||||
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
||||
GdkWaylandDisplay *display_wayland =
|
||||
GDK_WAYLAND_DISPLAY (gdk_window_get_display (impl->wrapper));
|
||||
|
||||
if (GDK_WINDOW_DESTROYED (impl->wrapper))
|
||||
return NULL;
|
||||
|
||||
if (!impl->cairo_surface)
|
||||
{
|
||||
GdkWaylandDisplay *display_wayland =
|
||||
GDK_WAYLAND_DISPLAY (gdk_window_get_display (impl->wrapper));
|
||||
|
||||
impl->cairo_surface =
|
||||
gdk_wayland_create_cairo_surface (display_wayland,
|
||||
impl->wrapper->width,
|
||||
impl->wrapper->height);
|
||||
}
|
||||
}
|
||||
|
||||
/* Unlike other backends the Cairo surface is not just a cheap wrapper
|
||||
* around some other backing. It is the buffer itself.
|
||||
*/
|
||||
static cairo_surface_t *
|
||||
gdk_wayland_window_ref_cairo_surface (GdkWindow *window)
|
||||
{
|
||||
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
||||
|
||||
if (GDK_WINDOW_DESTROYED (impl->wrapper))
|
||||
return NULL;
|
||||
|
||||
gdk_wayland_window_ensure_cairo_surface (window);
|
||||
|
||||
cairo_surface_reference (impl->cairo_surface);
|
||||
|
||||
@@ -507,6 +689,20 @@ gdk_wayland_window_ref_cairo_surface (GdkWindow *window)
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
gdk_window_impl_wayland_begin_paint_region (GdkWindow *window,
|
||||
const cairo_region_t *region)
|
||||
{
|
||||
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
||||
GdkWaylandCairoSurfaceData *data;
|
||||
|
||||
gdk_wayland_window_ensure_cairo_surface (window);
|
||||
data = cairo_surface_get_user_data (impl->cairo_surface,
|
||||
&gdk_wayland_cairo_key);
|
||||
|
||||
return data->busy;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_window_impl_wayland_finalize (GObject *object)
|
||||
{
|
||||
@@ -518,8 +714,6 @@ gdk_window_impl_wayland_finalize (GObject *object)
|
||||
|
||||
if (impl->cursor)
|
||||
g_object_unref (impl->cursor);
|
||||
if (impl->server_surface)
|
||||
cairo_surface_destroy (impl->server_surface);
|
||||
|
||||
G_OBJECT_CLASS (_gdk_window_impl_wayland_parent_class)->finalize (object);
|
||||
}
|
||||
@@ -638,6 +832,28 @@ gdk_wayland_window_map (GdkWindow *window)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
surface_enter (void *data,
|
||||
struct wl_surface *wl_surface,
|
||||
struct wl_output *output)
|
||||
{
|
||||
GdkWindow *window = GDK_WINDOW (data);
|
||||
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
||||
|
||||
impl->outputs = g_slist_prepend (impl->outputs, output);
|
||||
}
|
||||
|
||||
static void
|
||||
surface_leave (void *data,
|
||||
struct wl_surface *wl_surface,
|
||||
struct wl_output *output)
|
||||
{
|
||||
GdkWindow *window = GDK_WINDOW (data);
|
||||
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
||||
|
||||
impl->outputs = g_slist_remove (impl->outputs, output);
|
||||
}
|
||||
|
||||
static void
|
||||
shell_surface_handle_configure(void *data,
|
||||
struct wl_shell_surface *shell_surface,
|
||||
@@ -686,12 +902,30 @@ shell_surface_ping (void *data,
|
||||
wl_shell_surface_pong(shell_surface, serial);
|
||||
}
|
||||
|
||||
static const struct wl_surface_listener surface_listener = {
|
||||
surface_enter,
|
||||
surface_leave
|
||||
};
|
||||
|
||||
static const struct wl_shell_surface_listener shell_surface_listener = {
|
||||
shell_surface_ping,
|
||||
shell_surface_handle_configure,
|
||||
shell_surface_popup_done
|
||||
};
|
||||
|
||||
static void
|
||||
gdk_wayland_window_create_surface (GdkWindow *window)
|
||||
{
|
||||
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_window_get_display (window));
|
||||
|
||||
impl->surface = wl_compositor_create_surface (display_wayland->compositor);
|
||||
|
||||
wl_surface_set_user_data(impl->surface, window);
|
||||
wl_surface_add_listener(impl->surface,
|
||||
&surface_listener, window);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_window_show (GdkWindow *window, gboolean already_mapped)
|
||||
{
|
||||
@@ -709,10 +943,7 @@ gdk_wayland_window_show (GdkWindow *window, gboolean already_mapped)
|
||||
gdk_wayland_window_set_user_time (window, impl->user_time);
|
||||
|
||||
if (!impl->surface)
|
||||
{
|
||||
impl->surface = wl_compositor_create_surface(display_wayland->compositor);
|
||||
wl_surface_set_user_data(impl->surface, window);
|
||||
}
|
||||
gdk_wayland_window_create_surface (window);
|
||||
|
||||
if (!impl->shell_surface &&
|
||||
!impl->use_custom_surface &&
|
||||
@@ -738,7 +969,8 @@ gdk_wayland_window_show (GdkWindow *window, gboolean already_mapped)
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_window_hide (GdkWindow *window)
|
||||
gdk_wayland_window_hide_surface (GdkWindow *window,
|
||||
gboolean is_destroy)
|
||||
{
|
||||
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
||||
|
||||
@@ -746,7 +978,7 @@ gdk_wayland_window_hide (GdkWindow *window)
|
||||
{
|
||||
if (impl->shell_surface)
|
||||
wl_shell_surface_destroy(impl->shell_surface);
|
||||
if (impl->use_custom_surface)
|
||||
if (impl->use_custom_surface && !is_destroy)
|
||||
{
|
||||
wl_surface_attach (impl->surface, NULL, 0, 0);
|
||||
wl_surface_commit (impl->surface);
|
||||
@@ -755,21 +987,27 @@ gdk_wayland_window_hide (GdkWindow *window)
|
||||
{
|
||||
wl_surface_destroy(impl->surface);
|
||||
impl->surface = NULL;
|
||||
|
||||
g_slist_free (impl->outputs);
|
||||
impl->outputs = NULL;
|
||||
}
|
||||
impl->shell_surface = NULL;
|
||||
cairo_surface_destroy(impl->server_surface);
|
||||
impl->server_surface = NULL;
|
||||
impl->mapped = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_window_hide (GdkWindow *window)
|
||||
{
|
||||
gdk_wayland_window_hide_surface (window, FALSE);
|
||||
_gdk_window_clear_update_area (window);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_window_wayland_withdraw (GdkWindow *window)
|
||||
{
|
||||
GdkWindowImplWayland *impl;
|
||||
|
||||
if (!window->destroyed)
|
||||
{
|
||||
if (GDK_WINDOW_IS_MAPPED (window))
|
||||
@@ -777,26 +1015,7 @@ gdk_window_wayland_withdraw (GdkWindow *window)
|
||||
|
||||
g_assert (!GDK_WINDOW_IS_MAPPED (window));
|
||||
|
||||
impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
||||
if (impl->surface)
|
||||
{
|
||||
if (impl->shell_surface)
|
||||
wl_shell_surface_destroy(impl->shell_surface);
|
||||
if (impl->use_custom_surface)
|
||||
{
|
||||
wl_surface_attach (impl->surface, NULL, 0, 0);
|
||||
wl_surface_commit (impl->surface);
|
||||
}
|
||||
else if (impl->surface)
|
||||
{
|
||||
wl_surface_destroy(impl->surface);
|
||||
impl->surface = NULL;
|
||||
}
|
||||
impl->shell_surface = NULL;
|
||||
cairo_surface_destroy(impl->server_surface);
|
||||
impl->server_surface = NULL;
|
||||
impl->mapped = FALSE;
|
||||
}
|
||||
gdk_wayland_window_hide_surface (window, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1009,15 +1228,6 @@ gdk_wayland_window_queue_antiexpose (GdkWindow *window,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_window_translate (GdkWindow *window,
|
||||
cairo_region_t *area,
|
||||
gint dx,
|
||||
gint dy)
|
||||
{
|
||||
_gdk_window_invalidate_for_expose (window, area);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_window_destroy (GdkWindow *window,
|
||||
gboolean recursing,
|
||||
@@ -1027,22 +1237,20 @@ gdk_wayland_window_destroy (GdkWindow *window,
|
||||
|
||||
g_return_if_fail (GDK_IS_WINDOW (window));
|
||||
|
||||
/* We don't have nested windows */
|
||||
g_return_if_fail (!recursing);
|
||||
/* Wayland windows can't be externally destroyed; we may possibly
|
||||
* eventually want to use this path at display close-down */
|
||||
g_return_if_fail (!foreign_destroy);
|
||||
|
||||
gdk_wayland_window_hide_surface (window, TRUE);
|
||||
|
||||
if (impl->cairo_surface)
|
||||
{
|
||||
cairo_surface_finish (impl->cairo_surface);
|
||||
cairo_surface_set_user_data (impl->cairo_surface, &gdk_wayland_cairo_key,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
if (!recursing && !foreign_destroy)
|
||||
{
|
||||
if (impl->shell_surface)
|
||||
wl_shell_surface_destroy(impl->shell_surface);
|
||||
if (impl->surface)
|
||||
wl_surface_destroy(impl->surface);
|
||||
impl->shell_surface = NULL;
|
||||
impl->surface = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1623,8 +1831,10 @@ gdk_wayland_window_process_updates_recurse (GdkWindow *window,
|
||||
|
||||
gdk_wayland_window_map (window);
|
||||
|
||||
if (impl->cairo_surface)
|
||||
gdk_wayland_window_attach_image (window);
|
||||
gdk_wayland_window_ensure_cairo_surface (window);
|
||||
gdk_wayland_window_attach_image (window);
|
||||
|
||||
_gdk_window_process_updates_recurse (window, region);
|
||||
|
||||
n = cairo_region_num_rectangles(region);
|
||||
for (i = 0; i < n; i++)
|
||||
@@ -1632,10 +1842,8 @@ gdk_wayland_window_process_updates_recurse (GdkWindow *window,
|
||||
cairo_region_get_rectangle (region, i, &rect);
|
||||
wl_surface_damage (impl->surface,
|
||||
rect.x, rect.y, rect.width, rect.height);
|
||||
wl_surface_commit(impl->surface);
|
||||
impl->pending_commit = TRUE;
|
||||
}
|
||||
|
||||
_gdk_window_process_updates_recurse (window, region);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1726,12 +1934,12 @@ _gdk_window_impl_wayland_class_init (GdkWindowImplWaylandClass *klass)
|
||||
impl_class->input_shape_combine_region = gdk_window_wayland_input_shape_combine_region;
|
||||
impl_class->set_static_gravities = gdk_window_wayland_set_static_gravities;
|
||||
impl_class->queue_antiexpose = gdk_wayland_window_queue_antiexpose;
|
||||
impl_class->translate = gdk_wayland_window_translate;
|
||||
impl_class->destroy = gdk_wayland_window_destroy;
|
||||
impl_class->destroy_foreign = gdk_window_wayland_destroy_foreign;
|
||||
impl_class->resize_cairo_surface = gdk_window_wayland_resize_cairo_surface;
|
||||
impl_class->get_shape = gdk_wayland_window_get_shape;
|
||||
impl_class->get_input_shape = gdk_wayland_window_get_input_shape;
|
||||
impl_class->begin_paint_region = gdk_window_impl_wayland_begin_paint_region;
|
||||
/* impl_class->beep */
|
||||
|
||||
impl_class->focus = gdk_wayland_window_focus;
|
||||
@@ -1897,18 +2105,13 @@ void
|
||||
gdk_wayland_window_set_use_custom_surface (GdkWindow *window)
|
||||
{
|
||||
GdkWindowImplWayland *impl;
|
||||
GdkWaylandDisplay *display;
|
||||
|
||||
g_return_if_fail (GDK_IS_WAYLAND_WINDOW (window));
|
||||
|
||||
impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
||||
|
||||
if (!impl->surface)
|
||||
{
|
||||
display = GDK_WAYLAND_DISPLAY (gdk_window_get_display (window));
|
||||
impl->surface = wl_compositor_create_surface (display->compositor);
|
||||
wl_surface_set_user_data (impl->surface, window);
|
||||
}
|
||||
gdk_wayland_window_create_surface (window);
|
||||
|
||||
impl->use_custom_surface = TRUE;
|
||||
}
|
||||
|
||||
@@ -3319,77 +3319,6 @@ _gdk_win32_window_queue_antiexpose (GdkWindow *window,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Gets called from gdwindow.c(do_move_region_bits_on_impl)
|
||||
* and got tested with testgtk::big_window. Given the previous,
|
||||
* untested implementation this one looks much too simple ;)
|
||||
*/
|
||||
static void
|
||||
_gdk_win32_window_translate (GdkWindow *window,
|
||||
cairo_region_t *area, /* In impl window coords */
|
||||
gint dx,
|
||||
gint dy)
|
||||
{
|
||||
GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
|
||||
HRGN hrgn, area_hrgn;
|
||||
cairo_region_t *update_region;
|
||||
HDC hdc;
|
||||
int ret;
|
||||
|
||||
/* Note: This is the destination area, not the source, and
|
||||
it has been moved by dx, dy from the source area */
|
||||
area_hrgn = cairo_region_to_hrgn (area, 0, 0);
|
||||
|
||||
/* First we copy any outstanding invalid areas in the
|
||||
source area to the new position in the destination area */
|
||||
hrgn = CreateRectRgn (0, 0, 0, 0);
|
||||
ret = GetUpdateRgn (GDK_WINDOW_HWND (window), hrgn, FALSE);
|
||||
if (ret == ERROR)
|
||||
WIN32_API_FAILED ("GetUpdateRgn");
|
||||
else if (ret != NULLREGION)
|
||||
{
|
||||
/* Convert the source invalid region as it would be copied */
|
||||
OffsetRgn (hrgn, dx, dy);
|
||||
/* Keep what intersects the copy destination area */
|
||||
ret = CombineRgn (hrgn, hrgn, area_hrgn, RGN_AND);
|
||||
/* And invalidate it */
|
||||
if (ret == ERROR)
|
||||
WIN32_API_FAILED ("CombineRgn");
|
||||
else if (ret != NULLREGION)
|
||||
API_CALL (InvalidateRgn, (GDK_WINDOW_HWND (window), hrgn, TRUE));
|
||||
}
|
||||
|
||||
/* Then we copy the bits, invalidating whatever is copied from
|
||||
otherwise invisible areas */
|
||||
|
||||
hdc = _gdk_win32_impl_acquire_dc (impl);
|
||||
|
||||
/* Clip hdc to target region */
|
||||
API_CALL (SelectClipRgn, (hdc, area_hrgn));
|
||||
|
||||
SetRectRgn (hrgn, 0, 0, 0, 0);
|
||||
|
||||
if (!ScrollDC (hdc, dx, dy, NULL, NULL, hrgn, NULL))
|
||||
WIN32_GDI_FAILED ("ScrollDC");
|
||||
else
|
||||
{
|
||||
update_region = _gdk_win32_hrgn_to_region (hrgn);
|
||||
if (!cairo_region_is_empty (update_region))
|
||||
_gdk_window_invalidate_for_expose (window, update_region);
|
||||
cairo_region_destroy (update_region);
|
||||
}
|
||||
|
||||
/* Unset hdc clip region */
|
||||
API_CALL (SelectClipRgn, (hdc, NULL));
|
||||
|
||||
_gdk_win32_impl_release_dc (impl);
|
||||
|
||||
if (!DeleteObject (hrgn))
|
||||
WIN32_GDI_FAILED ("DeleteObject");
|
||||
|
||||
if (!DeleteObject (area_hrgn))
|
||||
WIN32_GDI_FAILED ("DeleteObject");
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_input_shape_combine_region (GdkWindow *window,
|
||||
const cairo_region_t *shape_region,
|
||||
@@ -3556,7 +3485,6 @@ gdk_window_impl_win32_class_init (GdkWindowImplWin32Class *klass)
|
||||
impl_class->input_shape_combine_region = gdk_win32_input_shape_combine_region;
|
||||
impl_class->set_static_gravities = gdk_win32_window_set_static_gravities;
|
||||
impl_class->queue_antiexpose = _gdk_win32_window_queue_antiexpose;
|
||||
impl_class->translate = _gdk_win32_window_translate;
|
||||
impl_class->destroy = gdk_win32_window_destroy;
|
||||
impl_class->destroy_foreign = gdk_win32_window_destroy_foreign;
|
||||
impl_class->resize_cairo_surface = gdk_win32_window_resize_cairo_surface;
|
||||
|
||||
@@ -2824,4 +2824,6 @@ gdk_x11_display_class_init (GdkX11DisplayClass * class)
|
||||
display_class->convert_selection = _gdk_x11_display_convert_selection;
|
||||
display_class->text_property_to_utf8_list = _gdk_x11_display_text_property_to_utf8_list;
|
||||
display_class->utf8_to_string_target = _gdk_x11_display_utf8_to_string_target;
|
||||
|
||||
_gdk_x11_windowing_init ();
|
||||
}
|
||||
|
||||
@@ -75,7 +75,6 @@ g_initable_iface_init (GInitableIface *iface)
|
||||
static void
|
||||
gdk_x11_display_manager_init (GdkX11DisplayManager *manager)
|
||||
{
|
||||
_gdk_x11_windowing_init ();
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -28,26 +28,11 @@
|
||||
typedef struct _GdkWindowQueueItem GdkWindowQueueItem;
|
||||
typedef struct _GdkWindowParentPos GdkWindowParentPos;
|
||||
|
||||
typedef enum {
|
||||
GDK_WINDOW_QUEUE_TRANSLATE,
|
||||
GDK_WINDOW_QUEUE_ANTIEXPOSE
|
||||
} GdkWindowQueueType;
|
||||
|
||||
struct _GdkWindowQueueItem
|
||||
{
|
||||
GdkWindow *window;
|
||||
gulong serial;
|
||||
GdkWindowQueueType type;
|
||||
union {
|
||||
struct {
|
||||
cairo_region_t *area;
|
||||
gint dx;
|
||||
gint dy;
|
||||
} translate;
|
||||
struct {
|
||||
cairo_region_t *area;
|
||||
} antiexpose;
|
||||
} u;
|
||||
cairo_region_t *antiexpose_area;
|
||||
};
|
||||
|
||||
void
|
||||
@@ -140,14 +125,7 @@ queue_item_free (GdkWindowQueueItem *item)
|
||||
(gpointer *)&(item->window));
|
||||
}
|
||||
|
||||
if (item->type == GDK_WINDOW_QUEUE_ANTIEXPOSE)
|
||||
cairo_region_destroy (item->u.antiexpose.area);
|
||||
else
|
||||
{
|
||||
if (item->u.translate.area)
|
||||
cairo_region_destroy (item->u.translate.area);
|
||||
}
|
||||
|
||||
cairo_region_destroy (item->antiexpose_area);
|
||||
g_free (item);
|
||||
}
|
||||
|
||||
@@ -213,11 +191,8 @@ gdk_window_queue (GdkWindow *window,
|
||||
GdkWindowQueueItem *item = tmp_list->data;
|
||||
GList *next = tmp_list->next;
|
||||
|
||||
if (item->type == GDK_WINDOW_QUEUE_ANTIEXPOSE)
|
||||
{
|
||||
queue_delete_link (display_x11->translate_queue, tmp_list);
|
||||
queue_item_free (item);
|
||||
}
|
||||
queue_delete_link (display_x11->translate_queue, tmp_list);
|
||||
queue_item_free (item);
|
||||
|
||||
tmp_list = next;
|
||||
}
|
||||
@@ -232,86 +207,12 @@ gdk_window_queue (GdkWindow *window,
|
||||
g_queue_push_tail (display_x11->translate_queue, item);
|
||||
}
|
||||
|
||||
static GC
|
||||
_get_scratch_gc (GdkWindow *window, cairo_region_t *clip_region)
|
||||
{
|
||||
GdkX11Screen *screen;
|
||||
XRectangle *rectangles;
|
||||
gint n_rects;
|
||||
gint depth;
|
||||
|
||||
screen = GDK_X11_SCREEN (gdk_window_get_screen (window));
|
||||
depth = gdk_visual_get_depth (gdk_window_get_visual (window)) - 1;
|
||||
|
||||
if (!screen->subwindow_gcs[depth])
|
||||
{
|
||||
XGCValues values;
|
||||
|
||||
values.graphics_exposures = True;
|
||||
values.subwindow_mode = IncludeInferiors;
|
||||
|
||||
screen->subwindow_gcs[depth] = XCreateGC (screen->xdisplay,
|
||||
GDK_WINDOW_XID (window),
|
||||
GCSubwindowMode | GCGraphicsExposures,
|
||||
&values);
|
||||
}
|
||||
|
||||
_gdk_x11_region_get_xrectangles (clip_region,
|
||||
0, 0,
|
||||
&rectangles,
|
||||
&n_rects);
|
||||
|
||||
XSetClipRectangles (screen->xdisplay,
|
||||
screen->subwindow_gcs[depth],
|
||||
0, 0,
|
||||
rectangles, n_rects,
|
||||
YXBanded);
|
||||
|
||||
g_free (rectangles);
|
||||
return screen->subwindow_gcs[depth];
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
_gdk_x11_window_translate (GdkWindow *window,
|
||||
cairo_region_t *area,
|
||||
gint dx,
|
||||
gint dy)
|
||||
{
|
||||
GdkWindowQueueItem *item;
|
||||
GC xgc;
|
||||
GdkRectangle extents;
|
||||
|
||||
cairo_region_get_extents (area, &extents);
|
||||
|
||||
xgc = _get_scratch_gc (window, area);
|
||||
|
||||
cairo_region_translate (area, -dx, -dy); /* Move to source region */
|
||||
|
||||
item = g_new (GdkWindowQueueItem, 1);
|
||||
item->type = GDK_WINDOW_QUEUE_TRANSLATE;
|
||||
item->u.translate.area = cairo_region_copy (area);
|
||||
item->u.translate.dx = dx;
|
||||
item->u.translate.dy = dy;
|
||||
gdk_window_queue (window, item);
|
||||
|
||||
XCopyArea (GDK_WINDOW_XDISPLAY (window),
|
||||
GDK_WINDOW_XID (window),
|
||||
GDK_WINDOW_XID (window),
|
||||
xgc,
|
||||
extents.x - dx, extents.y - dy,
|
||||
extents.width, extents.height,
|
||||
extents.x, extents.y);
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gdk_x11_window_queue_antiexpose (GdkWindow *window,
|
||||
cairo_region_t *area)
|
||||
{
|
||||
GdkWindowQueueItem *item = g_new (GdkWindowQueueItem, 1);
|
||||
item->type = GDK_WINDOW_QUEUE_ANTIEXPOSE;
|
||||
item->u.antiexpose.area = area;
|
||||
item->antiexpose_area = area;
|
||||
|
||||
gdk_window_queue (window, item);
|
||||
|
||||
@@ -339,28 +240,7 @@ _gdk_x11_window_process_expose (GdkWindow *window,
|
||||
if (serial - item->serial > (gulong) G_MAXLONG)
|
||||
{
|
||||
if (item->window == window)
|
||||
{
|
||||
if (item->type == GDK_WINDOW_QUEUE_TRANSLATE)
|
||||
{
|
||||
if (item->u.translate.area)
|
||||
{
|
||||
cairo_region_t *intersection;
|
||||
|
||||
intersection = cairo_region_copy (invalidate_region);
|
||||
cairo_region_intersect (intersection, item->u.translate.area);
|
||||
cairo_region_subtract (invalidate_region, intersection);
|
||||
cairo_region_translate (intersection, item->u.translate.dx, item->u.translate.dy);
|
||||
cairo_region_union (invalidate_region, intersection);
|
||||
cairo_region_destroy (intersection);
|
||||
}
|
||||
else
|
||||
cairo_region_translate (invalidate_region, item->u.translate.dx, item->u.translate.dy);
|
||||
}
|
||||
else /* anti-expose */
|
||||
{
|
||||
cairo_region_subtract (invalidate_region, item->u.antiexpose.area);
|
||||
}
|
||||
}
|
||||
cairo_region_subtract (invalidate_region, item->antiexpose_area);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -5334,7 +5334,6 @@ gdk_window_impl_x11_class_init (GdkWindowImplX11Class *klass)
|
||||
impl_class->input_shape_combine_region = gdk_window_x11_input_shape_combine_region;
|
||||
impl_class->set_static_gravities = gdk_window_x11_set_static_gravities;
|
||||
impl_class->queue_antiexpose = _gdk_x11_window_queue_antiexpose;
|
||||
impl_class->translate = _gdk_x11_window_translate;
|
||||
impl_class->destroy = gdk_x11_window_destroy;
|
||||
impl_class->destroy_foreign = gdk_x11_window_destroy_foreign;
|
||||
impl_class->resize_cairo_surface = gdk_window_x11_resize_cairo_surface;
|
||||
|
||||
@@ -314,6 +314,7 @@ gtk_public_h_sources = \
|
||||
gtkrecentchooserwidget.h \
|
||||
gtkrecentfilter.h \
|
||||
gtkrecentmanager.h \
|
||||
gtkrevealer.h \
|
||||
gtkscale.h \
|
||||
gtkscalebutton.h \
|
||||
gtkscrollable.h \
|
||||
@@ -518,6 +519,7 @@ gtk_private_h_sources = \
|
||||
gtkprintoperation-private.h \
|
||||
gtkprintutils.h \
|
||||
gtkprivate.h \
|
||||
gtkpixelcacheprivate.h \
|
||||
gtkquery.h \
|
||||
gtkrbtree.h \
|
||||
gtkrecentchooserdefault.h \
|
||||
@@ -799,6 +801,7 @@ gtk_base_c_sources = \
|
||||
gtkprivate.c \
|
||||
gtkprivatetypebuiltins.c \
|
||||
gtkprogressbar.c \
|
||||
gtkpixelcache.c \
|
||||
gtkradioaction.c \
|
||||
gtkradiobutton.c \
|
||||
gtkradiomenuitem.c \
|
||||
@@ -815,6 +818,7 @@ gtk_base_c_sources = \
|
||||
gtkrecentfilter.c \
|
||||
gtkrecentmanager.c \
|
||||
gtkresources.c \
|
||||
gtkrevealer.c \
|
||||
gtkroundedbox.c \
|
||||
gtkscale.c \
|
||||
gtkscalebutton.c \
|
||||
@@ -1354,7 +1358,9 @@ endif
|
||||
#
|
||||
# Installed tools
|
||||
#
|
||||
bin_PROGRAMS = gtk-query-immodules-3.0
|
||||
bin_PROGRAMS = \
|
||||
gtk-query-immodules-3.0 \
|
||||
gtk-launch
|
||||
|
||||
if BUILD_ICON_CACHE
|
||||
bin_PROGRAMS += gtk-update-icon-cache
|
||||
@@ -1401,11 +1407,8 @@ gtk_update_icon_cache_LDADD = $(GDK_PIXBUF_LIBS)
|
||||
gtk_update_icon_cache_SOURCES = updateiconcache.c
|
||||
endif
|
||||
|
||||
if HAVE_GIO_UNIX
|
||||
bin_PROGRAMS += gtk-launch
|
||||
gtk_launch_LDADD = $(LDADDS)
|
||||
gtk_launch_SOURCES = gtk-launch.c
|
||||
endif
|
||||
|
||||
noinst_PROGRAMS = extract-strings
|
||||
|
||||
@@ -1735,6 +1738,7 @@ endif
|
||||
|
||||
EXTRA_DIST += \
|
||||
$(STOCK_ICONS) \
|
||||
$(COMPOSITE_TEMPLATES) \
|
||||
$(DND_CURSORS) \
|
||||
$(GENERATED_ICONS) \
|
||||
gtk.def \
|
||||
|
||||
@@ -29,11 +29,9 @@ struct _GtkComboBoxAccessiblePrivate
|
||||
};
|
||||
|
||||
static void atk_action_interface_init (AtkActionIface *iface);
|
||||
static void atk_selection_interface_init (AtkSelectionIface *iface);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GtkComboBoxAccessible, gtk_combo_box_accessible, GTK_TYPE_CONTAINER_ACCESSIBLE,
|
||||
G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, atk_action_interface_init)
|
||||
G_IMPLEMENT_INTERFACE (ATK_TYPE_SELECTION, atk_selection_interface_init))
|
||||
G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, atk_action_interface_init))
|
||||
|
||||
static void
|
||||
changed_cb (GtkWidget *widget)
|
||||
@@ -52,7 +50,6 @@ changed_cb (GtkWidget *widget)
|
||||
{
|
||||
accessible->priv->old_selection = index;
|
||||
g_object_notify (G_OBJECT (obj), "accessible-name");
|
||||
g_signal_emit_by_name (obj, "selection-changed");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -333,106 +330,3 @@ atk_action_interface_init (AtkActionIface *iface)
|
||||
iface->get_localized_name = gtk_combo_box_accessible_action_get_localized_name;
|
||||
iface->get_description = gtk_combo_box_accessible_action_get_description;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_combo_box_accessible_add_selection (AtkSelection *selection,
|
||||
gint i)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
|
||||
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
|
||||
if (widget == NULL)
|
||||
return FALSE;
|
||||
|
||||
gtk_combo_box_set_active (GTK_COMBO_BOX (widget), i);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_combo_box_accessible_clear_selection (AtkSelection *selection)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
|
||||
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
|
||||
if (widget == NULL)
|
||||
return FALSE;
|
||||
|
||||
gtk_combo_box_set_active (GTK_COMBO_BOX (widget), -1);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static AtkObject *
|
||||
gtk_combo_box_accessible_ref_selection (AtkSelection *selection,
|
||||
gint i)
|
||||
{
|
||||
GtkComboBox *combo_box;
|
||||
GtkWidget *widget;
|
||||
AtkObject *obj;
|
||||
gint index;
|
||||
|
||||
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
|
||||
if (widget == NULL)
|
||||
return NULL;
|
||||
|
||||
if (i != 0)
|
||||
return NULL;
|
||||
|
||||
combo_box = GTK_COMBO_BOX (widget);
|
||||
|
||||
obj = gtk_combo_box_get_popup_accessible (combo_box);
|
||||
index = gtk_combo_box_get_active (combo_box);
|
||||
|
||||
return atk_object_ref_accessible_child (obj, index);
|
||||
}
|
||||
|
||||
static gint
|
||||
gtk_combo_box_accessible_get_selection_count (AtkSelection *selection)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
|
||||
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
|
||||
if (widget == NULL)
|
||||
return 0;
|
||||
|
||||
return (gtk_combo_box_get_active (GTK_COMBO_BOX (widget)) == -1) ? 0 : 1;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_combo_box_accessible_is_child_selected (AtkSelection *selection,
|
||||
gint i)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
gint j;
|
||||
|
||||
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
|
||||
|
||||
if (widget == NULL)
|
||||
return FALSE;
|
||||
|
||||
j = gtk_combo_box_get_active (GTK_COMBO_BOX (widget));
|
||||
|
||||
return (j == i);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_combo_box_accessible_remove_selection (AtkSelection *selection,
|
||||
gint i)
|
||||
{
|
||||
if (atk_selection_is_child_selected (selection, i))
|
||||
atk_selection_clear_selection (selection);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
atk_selection_interface_init (AtkSelectionIface *iface)
|
||||
{
|
||||
iface->add_selection = gtk_combo_box_accessible_add_selection;
|
||||
iface->clear_selection = gtk_combo_box_accessible_clear_selection;
|
||||
iface->ref_selection = gtk_combo_box_accessible_ref_selection;
|
||||
iface->get_selection_count = gtk_combo_box_accessible_get_selection_count;
|
||||
iface->is_child_selected = gtk_combo_box_accessible_is_child_selected;
|
||||
iface->remove_selection = gtk_combo_box_accessible_remove_selection;
|
||||
}
|
||||
|
||||
@@ -11,8 +11,6 @@
|
||||
<glade-widget-class name="GtkColorPlane" generic-name="colorplane" title="Color Plane" icon-name="widget-gtk-colorselection"/>
|
||||
<glade-widget-class name="GtkColorScale" generic-name="colorscale" title="Color Scale" icon-name="widget-gtk-colorselection"/>
|
||||
<glade-widget-class name="GtkScaleButtonScale" generic-name="scalebuttonscale" title="Scale Button Scale"/>
|
||||
<glade-widget-class name="ShortcutsPaneModelFilter" generic-name="shortcutsfilter" title="Shortcuts Filter"
|
||||
icon-name="widget-gtk-treemodelfilter"/>
|
||||
|
||||
<!-- gtkunixprint private widgets -->
|
||||
<glade-widget-class name="GtkPrinterOptionWidget" generic-name="printeroptionwidget" title="Printer Option Widget"
|
||||
@@ -22,7 +20,6 @@
|
||||
<property id="size" disabled="True"/>
|
||||
</properties>
|
||||
</glade-widget-class>
|
||||
<glade-widget-class name="GtkPlacesSidebar" generic-name="placessidebar" title="Places Sidebar"/>
|
||||
</glade-widget-classes>
|
||||
|
||||
<glade-widget-group name="gtk-private" title="Private GTK+ Classes">
|
||||
@@ -31,8 +28,6 @@
|
||||
<glade-widget-class-ref name="GtkColorPlane"/>
|
||||
<glade-widget-class-ref name="GtkColorScale"/>
|
||||
<glade-widget-class-ref name="GtkScaleButtonScale"/>
|
||||
<glade-widget-class-ref name="ShortcutsPaneModelFilter"/>
|
||||
<glade-widget-class-ref name="GtkPrinterOptionWidget"/>
|
||||
<glade-widget-class-ref name="GtkPlacesSidebar"/>
|
||||
</glade-widget-group>
|
||||
</glade-catalog>
|
||||
|
||||
@@ -163,6 +163,7 @@
|
||||
#include <gtk/gtkrecentchooserwidget.h>
|
||||
#include <gtk/gtkrecentfilter.h>
|
||||
#include <gtk/gtkrecentmanager.h>
|
||||
#include <gtk/gtkrevealer.h>
|
||||
#include <gtk/gtkscale.h>
|
||||
#include <gtk/gtkscalebutton.h>
|
||||
#include <gtk/gtkscrollable.h>
|
||||
|
||||
@@ -288,6 +288,7 @@ gtk_assistant_set_page_title
|
||||
gtk_assistant_set_page_type
|
||||
gtk_assistant_update_buttons_state
|
||||
gtk_attach_options_get_type
|
||||
gtk_baseline_position_get_type
|
||||
gtk_binding_entry_add_signal
|
||||
gtk_binding_entry_add_signall
|
||||
gtk_binding_entry_add_signal_from_string
|
||||
@@ -308,6 +309,7 @@ gtk_border_free
|
||||
gtk_border_get_type
|
||||
gtk_border_new
|
||||
gtk_border_style_get_type
|
||||
gtk_box_get_baseline_position
|
||||
gtk_box_get_homogeneous
|
||||
gtk_box_get_spacing
|
||||
gtk_box_get_type
|
||||
@@ -316,6 +318,7 @@ gtk_box_pack_end
|
||||
gtk_box_pack_start
|
||||
gtk_box_query_child_packing
|
||||
gtk_box_reorder_child
|
||||
gtk_box_set_baseline_position
|
||||
gtk_box_set_child_packing
|
||||
gtk_box_set_homogeneous
|
||||
gtk_box_set_spacing
|
||||
@@ -1199,9 +1202,11 @@ gtk_grab_get_current
|
||||
gtk_grab_remove
|
||||
gtk_grid_attach
|
||||
gtk_grid_attach_next_to
|
||||
gtk_grid_get_baseline_row
|
||||
gtk_grid_get_child_at
|
||||
gtk_grid_get_column_homogeneous
|
||||
gtk_grid_get_column_spacing
|
||||
gtk_grid_get_row_baseline_position
|
||||
gtk_grid_get_row_homogeneous
|
||||
gtk_grid_get_row_spacing
|
||||
gtk_grid_get_type
|
||||
@@ -1211,8 +1216,10 @@ gtk_grid_insert_row
|
||||
gtk_grid_new
|
||||
gtk_grid_remove_column
|
||||
gtk_grid_remove_row
|
||||
gtk_grid_set_baseline_row
|
||||
gtk_grid_set_column_homogeneous
|
||||
gtk_grid_set_column_spacing
|
||||
gtk_grid_set_row_baseline_position
|
||||
gtk_grid_set_row_homogeneous
|
||||
gtk_grid_set_row_spacing
|
||||
gtk_handle_box_get_child_detached
|
||||
@@ -1895,6 +1902,21 @@ gtk_parse_args
|
||||
gtk_path_bar_get_type
|
||||
gtk_path_priority_type_get_type
|
||||
gtk_path_type_get_type
|
||||
gtk_places_open_flags_get_type
|
||||
gtk_places_sidebar_add_shortcut
|
||||
gtk_places_sidebar_get_location
|
||||
gtk_places_sidebar_get_nth_bookmark
|
||||
gtk_places_sidebar_get_open_flags
|
||||
gtk_places_sidebar_get_show_connect_to_server
|
||||
gtk_places_sidebar_get_show_desktop
|
||||
gtk_places_sidebar_get_type
|
||||
gtk_places_sidebar_list_shortcuts
|
||||
gtk_places_sidebar_new
|
||||
gtk_places_sidebar_remove_shortcut
|
||||
gtk_places_sidebar_set_location
|
||||
gtk_places_sidebar_set_open_flags
|
||||
gtk_places_sidebar_set_show_connect_to_server
|
||||
gtk_places_sidebar_set_show_desktop
|
||||
#ifdef G_OS_UNIX
|
||||
gtk_plug_construct
|
||||
gtk_plug_construct_for_display
|
||||
@@ -2424,6 +2446,16 @@ gtk_requisition_get_type
|
||||
gtk_requisition_new
|
||||
gtk_resize_mode_get_type
|
||||
gtk_response_type_get_type
|
||||
gtk_revealer_new
|
||||
gtk_revealer_get_type
|
||||
gtk_revealer_get_reveal_child
|
||||
gtk_revealer_set_reveal_child
|
||||
gtk_revealer_get_child_revealed
|
||||
gtk_revealer_get_transition_duration
|
||||
gtk_revealer_set_transition_duration
|
||||
gtk_revealer_get_transition_type
|
||||
gtk_revealer_set_transition_type
|
||||
gtk_revealer_transition_type_get_type
|
||||
gtk_rgb_to_hsv
|
||||
gtk_scale_accessible_get_type
|
||||
gtk_scale_add_mark
|
||||
@@ -3737,6 +3769,7 @@ gtk_widget_error_bell
|
||||
gtk_widget_event
|
||||
gtk_widget_freeze_child_notify
|
||||
gtk_widget_get_accessible
|
||||
gtk_widget_get_allocated_baseline
|
||||
gtk_widget_get_allocated_height
|
||||
gtk_widget_get_allocated_width
|
||||
gtk_widget_get_allocation
|
||||
@@ -3779,8 +3812,10 @@ gtk_widget_get_parent_window
|
||||
gtk_widget_get_path
|
||||
gtk_widget_get_pointer
|
||||
gtk_widget_get_preferred_height
|
||||
gtk_widget_get_preferred_height_and_baseline_for_width
|
||||
gtk_widget_get_preferred_height_for_width
|
||||
gtk_widget_get_preferred_size
|
||||
gtk_widget_get_preferred_size_and_baseline
|
||||
gtk_widget_get_preferred_width
|
||||
gtk_widget_get_preferred_width_for_height
|
||||
gtk_widget_get_realized
|
||||
@@ -3803,6 +3838,7 @@ gtk_widget_get_tooltip_window
|
||||
gtk_widget_get_toplevel
|
||||
gtk_widget_get_type
|
||||
gtk_widget_get_valign
|
||||
gtk_widget_get_valign_with_baseline
|
||||
gtk_widget_get_vexpand
|
||||
gtk_widget_get_vexpand_set
|
||||
gtk_widget_get_visible
|
||||
@@ -3956,6 +3992,7 @@ gtk_widget_show
|
||||
gtk_widget_show_all
|
||||
gtk_widget_show_now
|
||||
gtk_widget_size_allocate
|
||||
gtk_widget_size_allocate_with_baseline
|
||||
gtk_widget_size_request
|
||||
gtk_widget_style_attach
|
||||
gtk_widget_style_get
|
||||
|
||||
@@ -108,6 +108,12 @@ static void gtk_alignment_get_preferred_height_for_width (GtkWidget *w
|
||||
gint for_size,
|
||||
gint *minimum_size,
|
||||
gint *natural_size);
|
||||
static void gtk_alignment_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
gint for_size,
|
||||
gint *minimum_size,
|
||||
gint *natural_size,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline);
|
||||
|
||||
G_DEFINE_TYPE (GtkAlignment, gtk_alignment, GTK_TYPE_BIN)
|
||||
|
||||
@@ -128,6 +134,7 @@ gtk_alignment_class_init (GtkAlignmentClass *class)
|
||||
widget_class->get_preferred_height = gtk_alignment_get_preferred_height;
|
||||
widget_class->get_preferred_width_for_height = gtk_alignment_get_preferred_width_for_height;
|
||||
widget_class->get_preferred_height_for_width = gtk_alignment_get_preferred_height_for_width;
|
||||
widget_class->get_preferred_height_and_baseline_for_width = gtk_alignment_get_preferred_height_and_baseline_for_width;
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_XALIGN,
|
||||
@@ -507,6 +514,7 @@ gtk_alignment_size_allocate (GtkWidget *widget,
|
||||
gint width, height;
|
||||
guint border_width;
|
||||
gint padding_horizontal, padding_vertical;
|
||||
gint baseline;
|
||||
|
||||
padding_horizontal = 0;
|
||||
padding_vertical = 0;
|
||||
@@ -520,6 +528,7 @@ gtk_alignment_size_allocate (GtkWidget *widget,
|
||||
gint child_nat_width;
|
||||
gint child_nat_height;
|
||||
gint child_width, child_height;
|
||||
double yalign, yscale;
|
||||
|
||||
border_width = gtk_container_get_border_width (GTK_CONTAINER (alignment));
|
||||
|
||||
@@ -529,6 +538,25 @@ gtk_alignment_size_allocate (GtkWidget *widget,
|
||||
width = MAX (1, allocation->width - padding_horizontal - 2 * border_width);
|
||||
height = MAX (1, allocation->height - padding_vertical - 2 * border_width);
|
||||
|
||||
baseline = gtk_widget_get_allocated_baseline (widget);
|
||||
if (baseline != -1)
|
||||
baseline -= border_width + priv->padding_top;
|
||||
|
||||
/* If we get a baseline set that means we're baseline aligned, and the parent
|
||||
honored that. In that case we have to ignore yalign/yscale as we need
|
||||
yalign based on the baseline and always FILL mode to ensure we can place
|
||||
the baseline anywhere */
|
||||
if (baseline != -1)
|
||||
{
|
||||
yalign = 0;
|
||||
yscale = 1.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
yalign = priv->yalign;
|
||||
yscale = priv->yscale;
|
||||
}
|
||||
|
||||
if (gtk_widget_get_request_mode (child) == GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
|
||||
{
|
||||
gtk_widget_get_preferred_width (child, NULL, &child_nat_width);
|
||||
@@ -559,8 +587,8 @@ gtk_alignment_size_allocate (GtkWidget *widget,
|
||||
|
||||
if (height > child_height)
|
||||
child_allocation.height = (child_height *
|
||||
(1.0 - priv->yscale) +
|
||||
height * priv->yscale);
|
||||
(1.0 - yscale) +
|
||||
height * yscale);
|
||||
else
|
||||
child_allocation.height = height;
|
||||
|
||||
@@ -569,9 +597,9 @@ gtk_alignment_size_allocate (GtkWidget *widget,
|
||||
else
|
||||
child_allocation.x = priv->xalign * (width - child_allocation.width) + allocation->x + border_width + priv->padding_left;
|
||||
|
||||
child_allocation.y = priv->yalign * (height - child_allocation.height) + allocation->y + border_width + priv->padding_top;
|
||||
child_allocation.y = yalign * (height - child_allocation.height) + allocation->y + border_width + priv->padding_top;
|
||||
|
||||
gtk_widget_size_allocate (child, &child_allocation);
|
||||
gtk_widget_size_allocate_with_baseline (child, &child_allocation, baseline);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -581,18 +609,30 @@ gtk_alignment_get_preferred_size (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
gint for_size,
|
||||
gint *minimum_size,
|
||||
gint *natural_size)
|
||||
gint *natural_size,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
GtkAlignment *alignment = GTK_ALIGNMENT (widget);
|
||||
GtkAlignmentPrivate *priv = alignment->priv;
|
||||
GtkWidget *child;
|
||||
guint minimum, natural;
|
||||
guint top_offset;
|
||||
guint border;
|
||||
|
||||
natural = minimum = gtk_container_get_border_width (GTK_CONTAINER (widget)) * 2;
|
||||
if (minimum_baseline)
|
||||
*minimum_baseline = -1;
|
||||
if (natural_baseline)
|
||||
*natural_baseline = -1;
|
||||
|
||||
border = gtk_container_get_border_width (GTK_CONTAINER (widget));
|
||||
natural = minimum = border * 2;
|
||||
top_offset = border;
|
||||
|
||||
if ((child = gtk_bin_get_child (GTK_BIN (widget))) && gtk_widget_get_visible (child))
|
||||
{
|
||||
gint child_min, child_nat;
|
||||
gint child_min_baseline = -1, child_nat_baseline = -1;
|
||||
|
||||
/* Request extra space for the padding: */
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
@@ -619,9 +659,10 @@ gtk_alignment_get_preferred_size (GtkWidget *widget,
|
||||
else
|
||||
{
|
||||
minimum += (priv->padding_top + priv->padding_bottom);
|
||||
top_offset += priv->padding_top;
|
||||
|
||||
if (for_size < 0)
|
||||
gtk_widget_get_preferred_height (child, &child_min, &child_nat);
|
||||
gtk_widget_get_preferred_height_and_baseline_for_width (child, -1, &child_min, &child_nat, &child_min_baseline, &child_nat_baseline);
|
||||
else
|
||||
{
|
||||
gint min_width;
|
||||
@@ -634,8 +675,13 @@ gtk_alignment_get_preferred_size (GtkWidget *widget,
|
||||
for_size = (min_width * (1.0 - priv->xscale) +
|
||||
for_size * priv->xscale);
|
||||
|
||||
gtk_widget_get_preferred_height_for_width (child, for_size, &child_min, &child_nat);
|
||||
gtk_widget_get_preferred_height_and_baseline_for_width (child, for_size, &child_min, &child_nat, &child_min_baseline, &child_nat_baseline);
|
||||
}
|
||||
|
||||
if (minimum_baseline && child_min_baseline >= 0)
|
||||
*minimum_baseline = child_min_baseline + top_offset;
|
||||
if (natural_baseline && child_nat_baseline >= 0)
|
||||
*natural_baseline = child_nat_baseline + top_offset;
|
||||
}
|
||||
|
||||
natural = minimum;
|
||||
@@ -656,7 +702,7 @@ gtk_alignment_get_preferred_width (GtkWidget *widget,
|
||||
gint *minimum_size,
|
||||
gint *natural_size)
|
||||
{
|
||||
gtk_alignment_get_preferred_size (widget, GTK_ORIENTATION_HORIZONTAL, -1, minimum_size, natural_size);
|
||||
gtk_alignment_get_preferred_size (widget, GTK_ORIENTATION_HORIZONTAL, -1, minimum_size, natural_size, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -664,7 +710,7 @@ gtk_alignment_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum_size,
|
||||
gint *natural_size)
|
||||
{
|
||||
gtk_alignment_get_preferred_size (widget, GTK_ORIENTATION_VERTICAL, -1, minimum_size, natural_size);
|
||||
gtk_alignment_get_preferred_size (widget, GTK_ORIENTATION_VERTICAL, -1, minimum_size, natural_size, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
@@ -674,7 +720,7 @@ gtk_alignment_get_preferred_width_for_height (GtkWidget *widget,
|
||||
gint *minimum_size,
|
||||
gint *natural_size)
|
||||
{
|
||||
gtk_alignment_get_preferred_size (widget, GTK_ORIENTATION_HORIZONTAL, for_size, minimum_size, natural_size);
|
||||
gtk_alignment_get_preferred_size (widget, GTK_ORIENTATION_HORIZONTAL, for_size, minimum_size, natural_size, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -683,9 +729,21 @@ gtk_alignment_get_preferred_height_for_width (GtkWidget *widget,
|
||||
gint *minimum_size,
|
||||
gint *natural_size)
|
||||
{
|
||||
gtk_alignment_get_preferred_size (widget, GTK_ORIENTATION_VERTICAL, for_size, minimum_size, natural_size);
|
||||
gtk_alignment_get_preferred_size (widget, GTK_ORIENTATION_VERTICAL, for_size, minimum_size, natural_size, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_alignment_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
gint for_size,
|
||||
gint *minimum_size,
|
||||
gint *natural_size,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
gtk_alignment_get_preferred_size (widget, GTK_ORIENTATION_VERTICAL, for_size, minimum_size, natural_size, minimum_baseline, natural_baseline);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gtk_alignment_set_padding:
|
||||
* @alignment: a #GtkAlignment
|
||||
|
||||
@@ -101,6 +101,12 @@ static void gtk_button_box_get_preferred_height_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum,
|
||||
gint *natural);
|
||||
static void gtk_button_box_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum,
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline);
|
||||
|
||||
static void gtk_button_box_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *allocation);
|
||||
@@ -143,6 +149,7 @@ gtk_button_box_class_init (GtkButtonBoxClass *class)
|
||||
widget_class->get_preferred_height = gtk_button_box_get_preferred_height;
|
||||
widget_class->get_preferred_width_for_height = gtk_button_box_get_preferred_width_for_height;
|
||||
widget_class->get_preferred_height_for_width = gtk_button_box_get_preferred_height_for_width;
|
||||
widget_class->get_preferred_height_and_baseline_for_width = gtk_button_box_get_preferred_height_and_baseline_for_width;
|
||||
widget_class->size_allocate = gtk_button_box_size_allocate;
|
||||
|
||||
container_class->remove = gtk_button_box_remove;
|
||||
@@ -438,7 +445,10 @@ gtk_button_box_child_requisition (GtkWidget *widget,
|
||||
gint *nvis_children,
|
||||
gint *nvis_secondaries,
|
||||
gint **widths,
|
||||
gint **heights)
|
||||
gint **heights,
|
||||
gint **baselines,
|
||||
gint *baseline,
|
||||
gint *baseline_height)
|
||||
{
|
||||
GtkButtonBox *bbox;
|
||||
GList *children, *list;
|
||||
@@ -446,6 +456,7 @@ gtk_button_box_child_requisition (GtkWidget *widget,
|
||||
gint nsecondaries;
|
||||
gint needed_width;
|
||||
gint needed_height;
|
||||
gint needed_above, needed_below;
|
||||
gint avg_w, avg_h;
|
||||
GtkRequisition child_requisition;
|
||||
gint ipad_w;
|
||||
@@ -456,11 +467,15 @@ gtk_button_box_child_requisition (GtkWidget *widget,
|
||||
gint ipad_y;
|
||||
gboolean homogeneous;
|
||||
gint i;
|
||||
gint max_above, max_below, child_baseline;
|
||||
GtkOrientation orientation;
|
||||
gboolean have_baseline;
|
||||
|
||||
g_return_if_fail (GTK_IS_BUTTON_BOX (widget));
|
||||
|
||||
bbox = GTK_BUTTON_BOX (widget);
|
||||
|
||||
orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (widget));
|
||||
homogeneous = gtk_box_get_homogeneous (GTK_BOX (widget));
|
||||
|
||||
gtk_widget_style_get (widget,
|
||||
@@ -475,22 +490,33 @@ gtk_button_box_child_requisition (GtkWidget *widget,
|
||||
list = children = _gtk_box_get_children (GTK_BOX (bbox));
|
||||
needed_width = child_min_width;
|
||||
needed_height = child_min_height;
|
||||
needed_above = 0;
|
||||
needed_below = 0;
|
||||
ipad_w = ipad_x * 2;
|
||||
ipad_h = ipad_y * 2;
|
||||
|
||||
have_baseline = FALSE;
|
||||
max_above = max_below = 0;
|
||||
avg_w = avg_h = 0;
|
||||
while (children)
|
||||
for (children = list; children != NULL; children = children->next)
|
||||
{
|
||||
GtkWidget *child;
|
||||
|
||||
child = children->data;
|
||||
children = children->next;
|
||||
|
||||
if (gtk_widget_get_visible (child))
|
||||
{
|
||||
nchildren += 1;
|
||||
gtk_widget_get_preferred_size (child,
|
||||
&child_requisition, NULL);
|
||||
gtk_widget_get_preferred_size_and_baseline (child,
|
||||
&child_requisition, NULL, &child_baseline, NULL);
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL &&
|
||||
gtk_widget_get_valign_with_baseline (child) == GTK_ALIGN_BASELINE &&
|
||||
child_baseline != -1)
|
||||
{
|
||||
have_baseline = TRUE;
|
||||
max_above = MAX (max_above, child_baseline + ipad_y);
|
||||
max_below = MAX (max_below , child_requisition.height + ipad_h - (child_baseline + ipad_y));
|
||||
}
|
||||
avg_w += child_requisition.width + ipad_w;
|
||||
avg_h += child_requisition.height + ipad_h;
|
||||
}
|
||||
@@ -498,8 +524,14 @@ gtk_button_box_child_requisition (GtkWidget *widget,
|
||||
avg_w /= MAX (nchildren, 1);
|
||||
avg_h /= MAX (nchildren, 1);
|
||||
|
||||
if (baseline)
|
||||
*baseline = have_baseline ? max_above : -1;
|
||||
if (baseline_height)
|
||||
*baseline_height = max_above + max_below;
|
||||
|
||||
*widths = g_new (gint, nchildren);
|
||||
*heights = g_new (gint, nchildren);
|
||||
*baselines = g_new (gint, nchildren);
|
||||
|
||||
i = 0;
|
||||
children = list;
|
||||
@@ -520,7 +552,8 @@ gtk_button_box_child_requisition (GtkWidget *widget,
|
||||
if (is_secondary)
|
||||
nsecondaries++;
|
||||
|
||||
gtk_widget_get_preferred_size (child, &child_requisition, NULL);
|
||||
gtk_widget_get_preferred_size_and_baseline (child,
|
||||
&child_requisition, NULL, &child_baseline, NULL);
|
||||
|
||||
if (homogeneous ||
|
||||
(!non_homogeneous && (child_requisition.width + ipad_w < avg_w * 1.5)))
|
||||
@@ -534,16 +567,38 @@ gtk_button_box_child_requisition (GtkWidget *widget,
|
||||
(*widths)[i] = child_requisition.width + ipad_w;
|
||||
}
|
||||
|
||||
(*baselines)[i] = -1;
|
||||
|
||||
if (homogeneous ||
|
||||
(!non_homogeneous && (child_requisition.height + ipad_h < avg_h * 1.5)))
|
||||
{
|
||||
(*heights)[i] = -1;
|
||||
if (child_requisition.height + ipad_h > needed_height)
|
||||
needed_height = child_requisition.height + ipad_h;
|
||||
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL &&
|
||||
gtk_widget_get_valign_with_baseline (child) == GTK_ALIGN_BASELINE &&
|
||||
child_baseline != -1)
|
||||
{
|
||||
(*baselines)[i] = child_baseline + ipad_y;
|
||||
|
||||
if (child_baseline + ipad_y > needed_above)
|
||||
needed_above = child_baseline + ipad_y;
|
||||
if (child_requisition.height - child_baseline + ipad_y > needed_below)
|
||||
needed_below = child_requisition.height - child_baseline + ipad_y;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (child_requisition.height + ipad_h > needed_height)
|
||||
needed_height = child_requisition.height + ipad_h;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
(*heights)[i] = child_requisition.height + ipad_h;
|
||||
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL &&
|
||||
gtk_widget_get_valign_with_baseline (child) == GTK_ALIGN_BASELINE &&
|
||||
child_baseline != -1)
|
||||
(*baselines)[i] = child_baseline + ipad_y;
|
||||
}
|
||||
|
||||
i++;
|
||||
@@ -552,12 +607,18 @@ gtk_button_box_child_requisition (GtkWidget *widget,
|
||||
|
||||
g_list_free (list);
|
||||
|
||||
needed_height = MAX (needed_height, needed_above + needed_below);
|
||||
|
||||
for (i = 0; i < nchildren; i++)
|
||||
{
|
||||
if ((*widths)[i] == -1)
|
||||
(*widths)[i] = needed_width;
|
||||
if ((*heights)[i] == -1)
|
||||
(*heights)[i] = needed_height;
|
||||
{
|
||||
(*heights)[i] = needed_height;
|
||||
if ((*baselines)[i] != -1)
|
||||
(*baselines)[i] = needed_above;
|
||||
}
|
||||
}
|
||||
|
||||
if (nvis_children)
|
||||
@@ -569,19 +630,24 @@ gtk_button_box_child_requisition (GtkWidget *widget,
|
||||
|
||||
static void
|
||||
gtk_button_box_size_request (GtkWidget *widget,
|
||||
GtkRequisition *requisition)
|
||||
GtkRequisition *requisition,
|
||||
gint *baseline)
|
||||
{
|
||||
GtkButtonBoxPrivate *priv;
|
||||
GtkButtonBox *bbox;
|
||||
gint nvis_children;
|
||||
gint max_size;
|
||||
gint max_size, max_above, max_below;
|
||||
gint total_size;
|
||||
gint spacing;
|
||||
GtkOrientation orientation;
|
||||
gint *widths;
|
||||
gint *heights;
|
||||
gint *baselines;
|
||||
gint i;
|
||||
|
||||
if (baseline)
|
||||
*baseline = -1;
|
||||
|
||||
bbox = GTK_BUTTON_BOX (widget);
|
||||
priv = bbox->priv;
|
||||
|
||||
@@ -591,16 +657,22 @@ gtk_button_box_size_request (GtkWidget *widget,
|
||||
gtk_button_box_child_requisition (widget,
|
||||
&nvis_children,
|
||||
NULL,
|
||||
&widths, &heights);
|
||||
&widths, &heights, &baselines, baseline, NULL);
|
||||
|
||||
max_size = 0;
|
||||
max_size = max_above = max_below = 0;
|
||||
total_size = 0;
|
||||
for (i = 0; i < nvis_children; i++)
|
||||
{
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
total_size += widths[i];
|
||||
max_size = MAX (max_size, heights[i]);
|
||||
if (baselines[i] == -1)
|
||||
max_size = MAX (max_size, heights[i]);
|
||||
else
|
||||
{
|
||||
max_above = MAX (max_above, baselines[i]);
|
||||
max_below = MAX (max_below, heights[i] - baselines[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -610,6 +682,23 @@ gtk_button_box_size_request (GtkWidget *widget,
|
||||
}
|
||||
g_free (widths);
|
||||
g_free (heights);
|
||||
g_free (baselines);
|
||||
|
||||
max_size = MAX (max_size, max_above + max_below);
|
||||
|
||||
switch (gtk_box_get_baseline_position (GTK_BOX (widget)))
|
||||
{
|
||||
case GTK_BASELINE_POSITION_TOP:
|
||||
break;
|
||||
case GTK_BASELINE_POSITION_CENTER:
|
||||
if (baseline != NULL && *baseline != -1)
|
||||
*baseline += (max_size - (max_above + max_below)) / 2;
|
||||
break;
|
||||
case GTK_BASELINE_POSITION_BOTTOM:
|
||||
if (baseline != NULL && *baseline != -1)
|
||||
*baseline += max_size - (max_above + max_below);
|
||||
break;
|
||||
}
|
||||
|
||||
if (nvis_children == 0)
|
||||
{
|
||||
@@ -656,7 +745,7 @@ gtk_button_box_get_preferred_width (GtkWidget *widget,
|
||||
{
|
||||
GtkRequisition requisition;
|
||||
|
||||
gtk_button_box_size_request (widget, &requisition);
|
||||
gtk_button_box_size_request (widget, &requisition, NULL);
|
||||
|
||||
*minimum = *natural = requisition.width;
|
||||
}
|
||||
@@ -666,11 +755,9 @@ gtk_button_box_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
{
|
||||
GtkRequisition requisition;
|
||||
|
||||
gtk_button_box_size_request (widget, &requisition);
|
||||
|
||||
*minimum = *natural = requisition.height;
|
||||
gtk_button_box_get_preferred_height_and_baseline_for_width (widget, -1,
|
||||
minimum, natural,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -691,6 +778,26 @@ gtk_button_box_get_preferred_height_for_width (GtkWidget *widget,
|
||||
gtk_button_box_get_preferred_height (widget, minimum, natural);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_button_box_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum,
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
GtkRequisition requisition;
|
||||
gint baseline;
|
||||
|
||||
gtk_button_box_size_request (widget, &requisition, &baseline);
|
||||
|
||||
*minimum = *natural = requisition.height;
|
||||
if (minimum_baseline)
|
||||
*minimum_baseline = baseline;
|
||||
if (natural_baseline)
|
||||
*natural_baseline = baseline;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_button_box_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *allocation)
|
||||
@@ -714,10 +821,13 @@ gtk_button_box_size_allocate (GtkWidget *widget,
|
||||
gint ipad_x, ipad_y;
|
||||
gint *widths;
|
||||
gint *heights;
|
||||
gint *baselines;
|
||||
gint *sizes;
|
||||
gint primary_size;
|
||||
gint secondary_size;
|
||||
gint total_size;
|
||||
gint baseline, baseline_height;
|
||||
gint child_baseline, allocated_baseline;
|
||||
gint i;
|
||||
|
||||
bbox = GTK_BUTTON_BOX (widget);
|
||||
@@ -733,7 +843,27 @@ gtk_button_box_size_allocate (GtkWidget *widget,
|
||||
gtk_button_box_child_requisition (widget,
|
||||
&nvis_children,
|
||||
&n_secondaries,
|
||||
&widths, &heights);
|
||||
&widths, &heights, &baselines, &baseline, &baseline_height);
|
||||
|
||||
allocated_baseline = gtk_widget_get_allocated_baseline (widget);
|
||||
if (allocated_baseline != -1)
|
||||
baseline = allocated_baseline;
|
||||
else if (baseline != -1)
|
||||
{
|
||||
/* TODO: modify baseline based on baseline_pos && allocated_baseline*/
|
||||
switch (gtk_box_get_baseline_position (GTK_BOX (widget)))
|
||||
{
|
||||
case GTK_BASELINE_POSITION_TOP:
|
||||
baseline = baseline;
|
||||
break;
|
||||
case GTK_BASELINE_POSITION_CENTER:
|
||||
baseline = baseline + (allocation->height - baseline_height) / 2;
|
||||
break;
|
||||
case GTK_BASELINE_POSITION_BOTTOM:
|
||||
baseline = allocation->height - (baseline_height - baseline);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
n_primaries = nvis_children - n_secondaries;
|
||||
primary_size = 0;
|
||||
@@ -917,10 +1047,17 @@ gtk_button_box_size_allocate (GtkWidget *widget,
|
||||
{
|
||||
child_allocation.width = widths[i];
|
||||
child_allocation.height = heights[i];
|
||||
child_baseline = -1;
|
||||
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
child_allocation.y = allocation->y + (allocation->height - child_allocation.height) / 2;
|
||||
if (baselines[i] != -1)
|
||||
{
|
||||
child_allocation.y = allocation->y + baseline - baselines[i];
|
||||
child_baseline = baselines[i];
|
||||
}
|
||||
else
|
||||
child_allocation.y = allocation->y + (allocation->height - child_allocation.height) / 2;
|
||||
|
||||
if (gtk_button_box_get_child_secondary (bbox, child))
|
||||
{
|
||||
@@ -953,7 +1090,7 @@ gtk_button_box_size_allocate (GtkWidget *widget,
|
||||
}
|
||||
}
|
||||
|
||||
gtk_widget_size_allocate (child, &child_allocation);
|
||||
gtk_widget_size_allocate_with_baseline (child, &child_allocation, child_baseline);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
@@ -961,6 +1098,7 @@ gtk_button_box_size_allocate (GtkWidget *widget,
|
||||
g_list_free (list);
|
||||
g_free (widths);
|
||||
g_free (heights);
|
||||
g_free (baselines);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -94,7 +94,8 @@ enum {
|
||||
PROP_0,
|
||||
PROP_ORIENTATION,
|
||||
PROP_SPACING,
|
||||
PROP_HOMOGENEOUS
|
||||
PROP_HOMOGENEOUS,
|
||||
PROP_BASELINE_POSITION
|
||||
};
|
||||
|
||||
enum {
|
||||
@@ -116,6 +117,7 @@ struct _GtkBoxPrivate
|
||||
guint default_expand : 1;
|
||||
guint homogeneous : 1;
|
||||
guint spacing_set : 1;
|
||||
guint baseline_pos : 2;
|
||||
};
|
||||
|
||||
typedef struct _GtkBoxChild GtkBoxChild;
|
||||
@@ -200,6 +202,12 @@ static void gtk_box_get_preferred_height_for_width (GtkWidget
|
||||
gint width,
|
||||
gint *minimum_height,
|
||||
gint *natural_height);
|
||||
static void gtk_box_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum_height,
|
||||
gint *natural_height,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline);
|
||||
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GtkBox, gtk_box, GTK_TYPE_CONTAINER,
|
||||
@@ -220,6 +228,7 @@ gtk_box_class_init (GtkBoxClass *class)
|
||||
widget_class->get_preferred_width = gtk_box_get_preferred_width;
|
||||
widget_class->get_preferred_height = gtk_box_get_preferred_height;
|
||||
widget_class->get_preferred_height_for_width = gtk_box_get_preferred_height_for_width;
|
||||
widget_class->get_preferred_height_and_baseline_for_width = gtk_box_get_preferred_height_and_baseline_for_width;
|
||||
widget_class->get_preferred_width_for_height = gtk_box_get_preferred_width_for_height;
|
||||
widget_class->compute_expand = gtk_box_compute_expand;
|
||||
widget_class->direction_changed = gtk_box_direction_changed;
|
||||
@@ -255,6 +264,15 @@ gtk_box_class_init (GtkBoxClass *class)
|
||||
FALSE,
|
||||
GTK_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_BASELINE_POSITION,
|
||||
g_param_spec_enum ("baseline-position",
|
||||
P_("Baseline position"),
|
||||
P_("The position of the baseline aligned widgets if extra space is availible"),
|
||||
GTK_TYPE_BASELINE_POSITION,
|
||||
GTK_BASELINE_POSITION_CENTER,
|
||||
GTK_PARAM_READWRITE));
|
||||
|
||||
/**
|
||||
* GtkBox:expand:
|
||||
*
|
||||
@@ -340,6 +358,7 @@ gtk_box_init (GtkBox *box)
|
||||
private->homogeneous = FALSE;
|
||||
private->spacing = 0;
|
||||
private->spacing_set = FALSE;
|
||||
private->baseline_pos = GTK_BASELINE_POSITION_CENTER;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -361,6 +380,9 @@ gtk_box_set_property (GObject *object,
|
||||
case PROP_SPACING:
|
||||
gtk_box_set_spacing (box, g_value_get_int (value));
|
||||
break;
|
||||
case PROP_BASELINE_POSITION:
|
||||
gtk_box_set_baseline_position (box, g_value_get_enum (value));
|
||||
break;
|
||||
case PROP_HOMOGENEOUS:
|
||||
gtk_box_set_homogeneous (box, g_value_get_boolean (value));
|
||||
break;
|
||||
@@ -387,6 +409,9 @@ gtk_box_get_property (GObject *object,
|
||||
case PROP_SPACING:
|
||||
g_value_set_int (value, private->spacing);
|
||||
break;
|
||||
case PROP_BASELINE_POSITION:
|
||||
g_value_set_enum (value, private->baseline_pos);
|
||||
break;
|
||||
case PROP_HOMOGENEOUS:
|
||||
g_value_set_boolean (value, private->homogeneous);
|
||||
break;
|
||||
@@ -435,6 +460,11 @@ gtk_box_size_allocate (GtkWidget *widget,
|
||||
GtkTextDirection direction;
|
||||
GtkAllocation child_allocation;
|
||||
GtkRequestedSize *sizes;
|
||||
gint child_minimum_baseline, child_natural_baseline;
|
||||
gint minimum_above, natural_above;
|
||||
gint minimum_below, natural_below;
|
||||
gboolean have_baseline;
|
||||
gint baseline;
|
||||
|
||||
GtkPackType packing;
|
||||
|
||||
@@ -461,6 +491,10 @@ gtk_box_size_allocate (GtkWidget *widget,
|
||||
else
|
||||
size = allocation->height - (nvis_children - 1) * private->spacing;
|
||||
|
||||
have_baseline = FALSE;
|
||||
minimum_above = natural_above = 0;
|
||||
minimum_below = natural_below = 0;
|
||||
|
||||
/* Retrieve desired size for visible children. */
|
||||
for (i = 0, children = private->children; children; children = children->next)
|
||||
{
|
||||
@@ -475,11 +509,11 @@ gtk_box_size_allocate (GtkWidget *widget,
|
||||
&sizes[i].minimum_size,
|
||||
&sizes[i].natural_size);
|
||||
else
|
||||
gtk_widget_get_preferred_height_for_width (child->widget,
|
||||
allocation->width,
|
||||
&sizes[i].minimum_size,
|
||||
&sizes[i].natural_size);
|
||||
|
||||
gtk_widget_get_preferred_height_and_baseline_for_width (child->widget,
|
||||
allocation->width,
|
||||
&sizes[i].minimum_size,
|
||||
&sizes[i].natural_size,
|
||||
NULL, NULL);
|
||||
|
||||
/* Assert the api is working properly */
|
||||
if (sizes[i].minimum_size < 0)
|
||||
@@ -537,28 +571,9 @@ gtk_box_size_allocate (GtkWidget *widget,
|
||||
extra = 0;
|
||||
}
|
||||
|
||||
/* Allocate child positions. */
|
||||
/* Allocate child sizes. */
|
||||
for (packing = GTK_PACK_START; packing <= GTK_PACK_END; ++packing)
|
||||
{
|
||||
if (private->orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
child_allocation.y = allocation->y;
|
||||
child_allocation.height = MAX (1, allocation->height);
|
||||
if (packing == GTK_PACK_START)
|
||||
x = allocation->x;
|
||||
else
|
||||
x = allocation->x + allocation->width;
|
||||
}
|
||||
else
|
||||
{
|
||||
child_allocation.x = allocation->x;
|
||||
child_allocation.width = MAX (1, allocation->width);
|
||||
if (packing == GTK_PACK_START)
|
||||
y = allocation->y;
|
||||
else
|
||||
y = allocation->y + allocation->height;
|
||||
}
|
||||
|
||||
for (i = 0, children = private->children;
|
||||
children;
|
||||
children = children->next)
|
||||
@@ -605,6 +620,105 @@ gtk_box_size_allocate (GtkWidget *widget,
|
||||
}
|
||||
}
|
||||
|
||||
sizes[i].natural_size = child_size;
|
||||
|
||||
if (private->orientation == GTK_ORIENTATION_HORIZONTAL &&
|
||||
gtk_widget_get_valign_with_baseline (child->widget) == GTK_ALIGN_BASELINE)
|
||||
{
|
||||
int child_allocation_width;
|
||||
int child_minimum_height, child_natural_height;
|
||||
|
||||
if (child->fill)
|
||||
child_allocation_width = MAX (1, child_size - child->padding * 2);
|
||||
else
|
||||
child_allocation_width = sizes[i].minimum_size;
|
||||
|
||||
child_minimum_baseline = -1;
|
||||
child_natural_baseline = -1;
|
||||
gtk_widget_get_preferred_height_and_baseline_for_width (child->widget,
|
||||
child_allocation_width,
|
||||
&child_minimum_height, &child_natural_height,
|
||||
&child_minimum_baseline, &child_natural_baseline);
|
||||
|
||||
if (child_minimum_baseline >= 0)
|
||||
{
|
||||
have_baseline = TRUE;
|
||||
minimum_below = MAX (minimum_below, child_minimum_height - child_minimum_baseline);
|
||||
natural_below = MAX (natural_below, child_natural_height - child_natural_baseline);
|
||||
minimum_above = MAX (minimum_above, child_minimum_baseline);
|
||||
natural_above = MAX (natural_above, child_natural_baseline);
|
||||
}
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
baseline = gtk_widget_get_allocated_baseline (widget);
|
||||
if (baseline == -1 && have_baseline)
|
||||
{
|
||||
gint height = MAX (1, allocation->height);
|
||||
|
||||
/* TODO: This is purely based on the minimum baseline, when things fit we should
|
||||
use the natural one? */
|
||||
|
||||
switch (private->baseline_pos)
|
||||
{
|
||||
case GTK_BASELINE_POSITION_TOP:
|
||||
baseline = minimum_above;
|
||||
break;
|
||||
case GTK_BASELINE_POSITION_CENTER:
|
||||
baseline = minimum_above + (height - (minimum_above + minimum_below)) / 2;
|
||||
break;
|
||||
case GTK_BASELINE_POSITION_BOTTOM:
|
||||
baseline = height - minimum_below;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate child positions. */
|
||||
for (packing = GTK_PACK_START; packing <= GTK_PACK_END; ++packing)
|
||||
{
|
||||
if (private->orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
child_allocation.y = allocation->y;
|
||||
child_allocation.height = MAX (1, allocation->height);
|
||||
if (packing == GTK_PACK_START)
|
||||
x = allocation->x;
|
||||
else
|
||||
x = allocation->x + allocation->width;
|
||||
}
|
||||
else
|
||||
{
|
||||
child_allocation.x = allocation->x;
|
||||
child_allocation.width = MAX (1, allocation->width);
|
||||
if (packing == GTK_PACK_START)
|
||||
y = allocation->y;
|
||||
else
|
||||
y = allocation->y + allocation->height;
|
||||
}
|
||||
|
||||
for (i = 0, children = private->children;
|
||||
children;
|
||||
children = children->next)
|
||||
{
|
||||
child = children->data;
|
||||
|
||||
/* If widget is not visible, skip it. */
|
||||
if (!gtk_widget_get_visible (child->widget))
|
||||
continue;
|
||||
|
||||
/* If widget is packed differently skip it, but still increment i,
|
||||
* since widget is visible and will be handled in next loop iteration.
|
||||
*/
|
||||
if (child->pack != packing)
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
child_size = sizes[i].natural_size;
|
||||
|
||||
/* Assign the child's position. */
|
||||
if (private->orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
@@ -658,7 +772,7 @@ gtk_box_size_allocate (GtkWidget *widget,
|
||||
child_allocation.y -= child_size;
|
||||
}
|
||||
}
|
||||
gtk_widget_size_allocate (child->widget, &child_allocation);
|
||||
gtk_widget_size_allocate_with_baseline (child->widget, &child_allocation, baseline);
|
||||
|
||||
i++;
|
||||
}
|
||||
@@ -677,10 +791,7 @@ gtk_box_compute_expand (GtkWidget *widget,
|
||||
gboolean opposite_expand;
|
||||
GtkOrientation opposite_orientation;
|
||||
|
||||
if (private->orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
opposite_orientation = GTK_ORIENTATION_VERTICAL;
|
||||
else
|
||||
opposite_orientation = GTK_ORIENTATION_HORIZONTAL;
|
||||
opposite_orientation = OPPOSITE_ORIENTATION (private->orientation);
|
||||
|
||||
our_expand = FALSE;
|
||||
opposite_expand = FALSE;
|
||||
@@ -1015,18 +1126,28 @@ static void
|
||||
gtk_box_get_size (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
gint *minimum_size,
|
||||
gint *natural_size)
|
||||
gint *natural_size,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
GtkBox *box;
|
||||
GtkBoxPrivate *private;
|
||||
GList *children;
|
||||
gint nvis_children;
|
||||
gint minimum, natural;
|
||||
gint minimum_above, natural_above;
|
||||
gint minimum_below, natural_below;
|
||||
gboolean have_baseline;
|
||||
gint min_baseline, nat_baseline;
|
||||
|
||||
box = GTK_BOX (widget);
|
||||
private = box->priv;
|
||||
|
||||
have_baseline = FALSE;
|
||||
minimum = natural = 0;
|
||||
minimum_above = natural_above = 0;
|
||||
minimum_below = natural_below = 0;
|
||||
min_baseline = nat_baseline = -1;
|
||||
|
||||
nvis_children = 0;
|
||||
|
||||
@@ -1037,13 +1158,15 @@ gtk_box_get_size (GtkWidget *widget,
|
||||
if (gtk_widget_get_visible (child->widget))
|
||||
{
|
||||
gint child_minimum, child_natural;
|
||||
gint child_minimum_baseline = -1, child_natural_baseline = -1;
|
||||
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
gtk_widget_get_preferred_width (child->widget,
|
||||
&child_minimum, &child_natural);
|
||||
else
|
||||
gtk_widget_get_preferred_height (child->widget,
|
||||
&child_minimum, &child_natural);
|
||||
gtk_widget_get_preferred_height_and_baseline_for_width (child->widget, -1,
|
||||
&child_minimum, &child_natural,
|
||||
&child_minimum_baseline, &child_natural_baseline);
|
||||
|
||||
if (private->orientation == orientation)
|
||||
{
|
||||
@@ -1065,9 +1188,20 @@ gtk_box_get_size (GtkWidget *widget,
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The biggest mins and naturals in the opposing orientation */
|
||||
minimum = MAX (minimum, child_minimum);
|
||||
natural = MAX (natural, child_natural);
|
||||
if (child_minimum_baseline >= 0)
|
||||
{
|
||||
have_baseline = TRUE;
|
||||
minimum_below = MAX (minimum_below, child_minimum - child_minimum_baseline);
|
||||
natural_below = MAX (natural_below, child_natural - child_natural_baseline);
|
||||
minimum_above = MAX (minimum_above, child_minimum_baseline);
|
||||
natural_above = MAX (natural_above, child_natural_baseline);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The biggest mins and naturals in the opposing orientation */
|
||||
minimum = MAX (minimum, child_minimum);
|
||||
natural = MAX (natural, child_natural);
|
||||
}
|
||||
}
|
||||
|
||||
nvis_children += 1;
|
||||
@@ -1085,11 +1219,39 @@ gtk_box_get_size (GtkWidget *widget,
|
||||
natural += (nvis_children - 1) * private->spacing;
|
||||
}
|
||||
|
||||
minimum = MAX (minimum, minimum_below + minimum_above);
|
||||
natural = MAX (natural, natural_below + natural_above);
|
||||
|
||||
if (have_baseline)
|
||||
{
|
||||
switch (private->baseline_pos)
|
||||
{
|
||||
case GTK_BASELINE_POSITION_TOP:
|
||||
min_baseline = minimum_above;
|
||||
nat_baseline = natural_above;
|
||||
break;
|
||||
case GTK_BASELINE_POSITION_CENTER:
|
||||
min_baseline = minimum_above + (minimum - (minimum_above + minimum_below)) / 2;
|
||||
nat_baseline = natural_above + (natural - (natural_above + natural_below)) / 2;
|
||||
break;
|
||||
case GTK_BASELINE_POSITION_BOTTOM:
|
||||
min_baseline = minimum - minimum_below;
|
||||
nat_baseline = natural - natural_below;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (minimum_size)
|
||||
*minimum_size = minimum;
|
||||
|
||||
if (natural_size)
|
||||
*natural_size = natural;
|
||||
|
||||
if (minimum_baseline)
|
||||
*minimum_baseline = min_baseline;
|
||||
|
||||
if (natural_baseline)
|
||||
*natural_baseline = nat_baseline;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1097,7 +1259,7 @@ gtk_box_get_preferred_width (GtkWidget *widget,
|
||||
gint *minimum_size,
|
||||
gint *natural_size)
|
||||
{
|
||||
gtk_box_get_size (widget, GTK_ORIENTATION_HORIZONTAL, minimum_size, natural_size);
|
||||
gtk_box_get_size (widget, GTK_ORIENTATION_HORIZONTAL, minimum_size, natural_size, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1105,14 +1267,16 @@ gtk_box_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum_size,
|
||||
gint *natural_size)
|
||||
{
|
||||
gtk_box_get_size (widget, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size);
|
||||
gtk_box_get_size (widget, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_box_compute_size_for_opposing_orientation (GtkBox *box,
|
||||
gint avail_size,
|
||||
gint *minimum_size,
|
||||
gint *natural_size)
|
||||
gint *natural_size,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
GtkBoxPrivate *private = box->priv;
|
||||
GtkBoxChild *child;
|
||||
@@ -1120,11 +1284,16 @@ gtk_box_compute_size_for_opposing_orientation (GtkBox *box,
|
||||
gint nvis_children;
|
||||
gint nexpand_children;
|
||||
gint computed_minimum = 0, computed_natural = 0;
|
||||
gint computed_minimum_above = 0, computed_natural_above = 0;
|
||||
gint computed_minimum_below = 0, computed_natural_below = 0;
|
||||
gint computed_minimum_baseline = -1, computed_natural_baseline = -1;
|
||||
GtkRequestedSize *sizes;
|
||||
GtkPackType packing;
|
||||
gint size, extra, i;
|
||||
gint child_size, child_minimum, child_natural;
|
||||
gint child_minimum_baseline, child_natural_baseline;
|
||||
gint n_extra_widgets = 0;
|
||||
gboolean have_baseline;
|
||||
|
||||
count_expand_children (box, &nvis_children, &nexpand_children);
|
||||
|
||||
@@ -1199,6 +1368,7 @@ gtk_box_compute_size_for_opposing_orientation (GtkBox *box,
|
||||
extra = 0;
|
||||
}
|
||||
|
||||
have_baseline = FALSE;
|
||||
/* Allocate child positions. */
|
||||
for (packing = GTK_PACK_START; packing <= GTK_PACK_END; ++packing)
|
||||
{
|
||||
@@ -1260,26 +1430,64 @@ gtk_box_compute_size_for_opposing_orientation (GtkBox *box,
|
||||
}
|
||||
|
||||
|
||||
child_minimum_baseline = child_natural_baseline = -1;
|
||||
/* Assign the child's position. */
|
||||
if (private->orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
gtk_widget_get_preferred_height_for_width (child->widget,
|
||||
child_size, &child_minimum, &child_natural);
|
||||
gtk_widget_get_preferred_height_and_baseline_for_width (child->widget, child_size,
|
||||
&child_minimum, &child_natural,
|
||||
&child_minimum_baseline, &child_natural_baseline);
|
||||
else /* (private->orientation == GTK_ORIENTATION_VERTICAL) */
|
||||
gtk_widget_get_preferred_width_for_height (child->widget,
|
||||
child_size, &child_minimum, &child_natural);
|
||||
|
||||
|
||||
computed_minimum = MAX (computed_minimum, child_minimum);
|
||||
computed_natural = MAX (computed_natural, child_natural);
|
||||
if (child_minimum_baseline >= 0)
|
||||
{
|
||||
have_baseline = TRUE;
|
||||
computed_minimum_below = MAX (computed_minimum_below, child_minimum - child_minimum_baseline);
|
||||
computed_natural_below = MAX (computed_natural_below, child_natural - child_natural_baseline);
|
||||
computed_minimum_above = MAX (computed_minimum_above, child_minimum_baseline);
|
||||
computed_natural_above = MAX (computed_natural_above, child_natural_baseline);
|
||||
}
|
||||
else
|
||||
{
|
||||
computed_minimum = MAX (computed_minimum, child_minimum);
|
||||
computed_natural = MAX (computed_natural, child_natural);
|
||||
}
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (have_baseline)
|
||||
{
|
||||
computed_minimum = MAX (computed_minimum, computed_minimum_below + computed_minimum_above);
|
||||
computed_natural = MAX (computed_natural, computed_natural_below + computed_natural_above);
|
||||
switch (private->baseline_pos)
|
||||
{
|
||||
case GTK_BASELINE_POSITION_TOP:
|
||||
computed_minimum_baseline = computed_minimum_above;
|
||||
computed_natural_baseline = computed_natural_above;
|
||||
break;
|
||||
case GTK_BASELINE_POSITION_CENTER:
|
||||
computed_minimum_baseline = computed_minimum_above + MAX((computed_minimum - (computed_minimum_above + computed_minimum_below)) / 2, 0);
|
||||
computed_natural_baseline = computed_natural_above + MAX((computed_natural - (computed_natural_above + computed_natural_below)) / 2, 0);
|
||||
break;
|
||||
case GTK_BASELINE_POSITION_BOTTOM:
|
||||
computed_minimum_baseline = computed_minimum - computed_minimum_below;
|
||||
computed_natural_baseline = computed_natural - computed_natural_below;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (minimum_baseline)
|
||||
*minimum_baseline = computed_minimum_baseline;
|
||||
if (natural_baseline)
|
||||
*natural_baseline = computed_natural_baseline;
|
||||
|
||||
if (minimum_size)
|
||||
*minimum_size = computed_minimum;
|
||||
if (natural_size)
|
||||
*natural_size = computed_natural;
|
||||
*natural_size = MAX (computed_natural, computed_natural_below + computed_natural_above);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1355,24 +1563,46 @@ gtk_box_get_preferred_width_for_height (GtkWidget *widget,
|
||||
GtkBoxPrivate *private = box->priv;
|
||||
|
||||
if (private->orientation == GTK_ORIENTATION_VERTICAL)
|
||||
gtk_box_compute_size_for_opposing_orientation (box, height, minimum_width, natural_width);
|
||||
gtk_box_compute_size_for_opposing_orientation (box, height, minimum_width, natural_width, NULL, NULL);
|
||||
else
|
||||
gtk_box_compute_size_for_orientation (box, height, minimum_width, natural_width);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_box_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum_height,
|
||||
gint *natural_height,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
GtkBox *box = GTK_BOX (widget);
|
||||
GtkBoxPrivate *private = box->priv;
|
||||
|
||||
if (width < 0)
|
||||
gtk_box_get_size (widget, GTK_ORIENTATION_VERTICAL, minimum_height, natural_height, minimum_baseline, natural_baseline);
|
||||
else
|
||||
{
|
||||
if (private->orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
gtk_box_compute_size_for_opposing_orientation (box, width, minimum_height, natural_height, minimum_baseline, natural_baseline);
|
||||
else
|
||||
{
|
||||
if (minimum_baseline)
|
||||
*minimum_baseline = -1;
|
||||
if (natural_baseline)
|
||||
*natural_baseline = -1;
|
||||
gtk_box_compute_size_for_orientation (box, width, minimum_height, natural_height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_box_get_preferred_height_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum_height,
|
||||
gint *natural_height)
|
||||
{
|
||||
GtkBox *box = GTK_BOX (widget);
|
||||
GtkBoxPrivate *private = box->priv;
|
||||
|
||||
if (private->orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
gtk_box_compute_size_for_opposing_orientation (box, width, minimum_height, natural_height);
|
||||
else
|
||||
gtk_box_compute_size_for_orientation (box, width, minimum_height, natural_height);
|
||||
gtk_box_get_preferred_height_and_baseline_for_width (widget, width, minimum_height, natural_height, NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1550,6 +1780,59 @@ gtk_box_get_spacing (GtkBox *box)
|
||||
return box->priv->spacing;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_box_set_baseline_position:
|
||||
* @box: a #GtkBox
|
||||
* @position: a #GtkBaselinePosition
|
||||
*
|
||||
* Sets the baseline position of a box. This affects
|
||||
* only horizontal boxes with at least one baseline aligned
|
||||
* child. If there is more vertical space availible than requested,
|
||||
* and the baseline is not allocated by the parent then
|
||||
* @position is used to allocate the baseline wrt the
|
||||
* extra space available.
|
||||
*
|
||||
* Since: 3.10
|
||||
*/
|
||||
void
|
||||
gtk_box_set_baseline_position (GtkBox *box,
|
||||
GtkBaselinePosition position)
|
||||
{
|
||||
GtkBoxPrivate *private;
|
||||
|
||||
g_return_if_fail (GTK_IS_BOX (box));
|
||||
|
||||
private = box->priv;
|
||||
|
||||
if (position != private->baseline_pos)
|
||||
{
|
||||
private->baseline_pos = position;
|
||||
|
||||
g_object_notify (G_OBJECT (box), "baseline-position");
|
||||
|
||||
gtk_widget_queue_resize (GTK_WIDGET (box));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_box_get_baseline_position:
|
||||
* @box: a #GtkBox
|
||||
*
|
||||
* Gets the value set by gtk_box_set_baseline_position().
|
||||
*
|
||||
* Return value: the baseline position
|
||||
*
|
||||
* Since: 3.10
|
||||
**/
|
||||
GtkBaselinePosition
|
||||
gtk_box_get_baseline_position (GtkBox *box)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_BOX (box), GTK_BASELINE_POSITION_CENTER);
|
||||
|
||||
return box->priv->baseline_pos;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_gtk_box_set_spacing_set (GtkBox *box,
|
||||
gboolean spacing_set)
|
||||
|
||||
@@ -89,6 +89,11 @@ gboolean gtk_box_get_homogeneous (GtkBox *box);
|
||||
void gtk_box_set_spacing (GtkBox *box,
|
||||
gint spacing);
|
||||
gint gtk_box_get_spacing (GtkBox *box);
|
||||
GDK_AVAILABLE_IN_3_10
|
||||
void gtk_box_set_baseline_position (GtkBox *box,
|
||||
GtkBaselinePosition position);
|
||||
GDK_AVAILABLE_IN_3_10
|
||||
GtkBaselinePosition gtk_box_get_baseline_position (GtkBox *box);
|
||||
|
||||
void gtk_box_reorder_child (GtkBox *box,
|
||||
GtkWidget *child,
|
||||
|
||||
@@ -1015,19 +1015,19 @@ start_element (GMarkupParseContext *context,
|
||||
element_name);
|
||||
}
|
||||
|
||||
gchar *
|
||||
const gchar *
|
||||
_gtk_builder_parser_translate (const gchar *domain,
|
||||
const gchar *context,
|
||||
const gchar *text)
|
||||
{
|
||||
const char *s;
|
||||
const gchar *s;
|
||||
|
||||
if (context)
|
||||
s = g_dpgettext2 (domain, context, text);
|
||||
else
|
||||
s = g_dgettext (domain, text);
|
||||
|
||||
return g_strdup (s);
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Called for close tags </foo> */
|
||||
@@ -1128,15 +1128,14 @@ end_element (GMarkupParseContext *context,
|
||||
|
||||
if (prop_info->translatable && prop_info->text->len)
|
||||
{
|
||||
prop_info->data = _gtk_builder_parser_translate (data->domain,
|
||||
prop_info->context,
|
||||
prop_info->text->str);
|
||||
prop_info->data = g_strdup (_gtk_builder_parser_translate (data->domain,
|
||||
prop_info->context,
|
||||
prop_info->text->str));
|
||||
g_string_free (prop_info->text, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
prop_info->data = g_string_free (prop_info->text, FALSE);
|
||||
|
||||
}
|
||||
|
||||
object_info->properties =
|
||||
|
||||
@@ -148,9 +148,9 @@ gboolean _gtk_builder_flags_from_string (GType type,
|
||||
const char *string,
|
||||
guint *value,
|
||||
GError **error);
|
||||
gchar * _gtk_builder_parser_translate (const gchar *domain,
|
||||
const gchar *context,
|
||||
const gchar *text);
|
||||
const gchar * _gtk_builder_parser_translate (const gchar *domain,
|
||||
const gchar *context,
|
||||
const gchar *text);
|
||||
gchar * _gtk_builder_get_resource_path (GtkBuilder *builder,
|
||||
const gchar *string);
|
||||
gchar * _gtk_builder_get_absolute_filename (GtkBuilder *builder,
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
#include "gtkactivatable.h"
|
||||
#include "gtksizerequest.h"
|
||||
#include "gtktypebuiltins.h"
|
||||
#include "gtkwidgetprivate.h"
|
||||
#include "gtkprivate.h"
|
||||
#include "gtkintl.h"
|
||||
#include "a11y/gtkbuttonaccessible.h"
|
||||
@@ -164,12 +165,26 @@ static void gtk_button_set_related_action (GtkButton *button,
|
||||
static void gtk_button_set_use_action_appearance (GtkButton *button,
|
||||
gboolean use_appearance);
|
||||
|
||||
static void gtk_button_get_preferred_width (GtkWidget *widget,
|
||||
gint *minimum_size,
|
||||
gint *natural_size);
|
||||
static void gtk_button_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum_size,
|
||||
gint *natural_size);
|
||||
static void gtk_button_get_preferred_width (GtkWidget *widget,
|
||||
gint *minimum_size,
|
||||
gint *natural_size);
|
||||
static void gtk_button_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum_size,
|
||||
gint *natural_size);
|
||||
static void gtk_button_get_preferred_width_for_height (GtkWidget *widget,
|
||||
gint for_size,
|
||||
gint *minimum_size,
|
||||
gint *natural_size);
|
||||
static void gtk_button_get_preferred_height_for_width (GtkWidget *widget,
|
||||
gint for_size,
|
||||
gint *minimum_size,
|
||||
gint *natural_size);
|
||||
static void gtk_button_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum_size,
|
||||
gint *natural_size,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline);
|
||||
|
||||
static guint button_signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
@@ -194,8 +209,11 @@ gtk_button_class_init (GtkButtonClass *klass)
|
||||
gobject_class->set_property = gtk_button_set_property;
|
||||
gobject_class->get_property = gtk_button_get_property;
|
||||
|
||||
widget_class->get_preferred_width = gtk_button_get_preferred_width;
|
||||
widget_class->get_preferred_width = gtk_button_get_preferred_width;
|
||||
widget_class->get_preferred_height = gtk_button_get_preferred_height;
|
||||
widget_class->get_preferred_width_for_height = gtk_button_get_preferred_width_for_height;
|
||||
widget_class->get_preferred_height_for_width = gtk_button_get_preferred_height_for_width;
|
||||
widget_class->get_preferred_height_and_baseline_for_width = gtk_button_get_preferred_height_and_baseline_for_width;
|
||||
widget_class->destroy = gtk_button_destroy;
|
||||
widget_class->screen_changed = gtk_button_screen_changed;
|
||||
widget_class->realize = gtk_button_realize;
|
||||
@@ -1150,11 +1168,16 @@ gtk_button_construct_child (GtkButton *button)
|
||||
else
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, image_spacing);
|
||||
|
||||
gtk_widget_set_valign (image, GTK_ALIGN_BASELINE);
|
||||
gtk_widget_set_valign (box, GTK_ALIGN_BASELINE);
|
||||
|
||||
if (priv->align_set)
|
||||
align = gtk_alignment_new (priv->xalign, priv->yalign, 0.0, 0.0);
|
||||
else
|
||||
align = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
|
||||
|
||||
gtk_widget_set_valign (align, GTK_ALIGN_BASELINE);
|
||||
|
||||
if (priv->image_position == GTK_POS_LEFT ||
|
||||
priv->image_position == GTK_POS_TOP)
|
||||
gtk_box_pack_start (GTK_BOX (box), priv->image, FALSE, FALSE, 0);
|
||||
@@ -1172,6 +1195,8 @@ gtk_button_construct_child (GtkButton *button)
|
||||
else
|
||||
label = gtk_label_new (label_text);
|
||||
|
||||
gtk_widget_set_valign (label, GTK_ALIGN_BASELINE);
|
||||
|
||||
if (priv->image_position == GTK_POS_RIGHT ||
|
||||
priv->image_position == GTK_POS_BOTTOM)
|
||||
gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
|
||||
@@ -1196,6 +1221,8 @@ gtk_button_construct_child (GtkButton *button)
|
||||
else
|
||||
label = gtk_label_new (priv->label_text);
|
||||
|
||||
gtk_widget_set_valign (label, GTK_ALIGN_BASELINE);
|
||||
|
||||
if (priv->align_set)
|
||||
gtk_misc_set_alignment (GTK_MISC (label), priv->xalign, priv->yalign);
|
||||
|
||||
@@ -1570,29 +1597,48 @@ gtk_button_get_props (GtkButton *button,
|
||||
gtk_style_context_get_border (context, state, border);
|
||||
}
|
||||
|
||||
/* Computes the size of the border around the button's child
|
||||
* including all CSS and style properties so it can be used
|
||||
* during size allocation and size request phases. */
|
||||
static void
|
||||
gtk_button_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *allocation)
|
||||
gtk_button_get_full_border (GtkButton *button,
|
||||
GtkBorder *full_border)
|
||||
{
|
||||
GtkButton *button = GTK_BUTTON (widget);
|
||||
GtkButtonPrivate *priv = button->priv;
|
||||
GtkAllocation child_allocation;
|
||||
GtkWidget *widget = GTK_WIDGET (button);
|
||||
GtkStyleContext *context;
|
||||
GtkWidget *child;
|
||||
GtkBorder default_border;
|
||||
GtkBorder padding;
|
||||
GtkBorder border;
|
||||
gint focus_width;
|
||||
gint focus_pad;
|
||||
GtkBorder default_border, padding, border;
|
||||
int focus_width, focus_pad;
|
||||
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
|
||||
gtk_button_get_props (button, &default_border, NULL,
|
||||
&padding, &border, NULL);
|
||||
gtk_style_context_get_style (context,
|
||||
"focus-line-width", &focus_width,
|
||||
"focus-padding", &focus_pad,
|
||||
NULL);
|
||||
"focus-line-width", &focus_width,
|
||||
"focus-padding", &focus_pad,
|
||||
NULL);
|
||||
|
||||
full_border->left = padding.left + border.left + focus_width + focus_pad;
|
||||
full_border->right = padding.right + border.right + focus_width + focus_pad;
|
||||
full_border->top = padding.top + border.top + focus_width + focus_pad;
|
||||
full_border->bottom = padding.bottom + border.bottom + focus_width + focus_pad;
|
||||
|
||||
if (gtk_widget_get_can_default (GTK_WIDGET (button)))
|
||||
{
|
||||
full_border->left += default_border.left;
|
||||
full_border->right += default_border.right;
|
||||
full_border->top += default_border.top;
|
||||
full_border->bottom += default_border.bottom;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_button_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *allocation)
|
||||
{
|
||||
GtkButton *button = GTK_BUTTON (widget);
|
||||
GtkButtonPrivate *priv = button->priv;
|
||||
GtkWidget *child;
|
||||
|
||||
gtk_widget_set_allocation (widget, allocation);
|
||||
|
||||
@@ -1606,52 +1652,40 @@ gtk_button_size_allocate (GtkWidget *widget,
|
||||
child = gtk_bin_get_child (GTK_BIN (button));
|
||||
if (child && gtk_widget_get_visible (child))
|
||||
{
|
||||
child_allocation.x = allocation->x + padding.left + border.left;
|
||||
child_allocation.y = allocation->y + padding.top + border.top;
|
||||
GtkAllocation child_allocation;
|
||||
GtkBorder border;
|
||||
gint baseline;
|
||||
|
||||
child_allocation.width =
|
||||
allocation->width -
|
||||
(padding.left + padding.right) -
|
||||
(border.left + border.right);
|
||||
gtk_button_get_full_border (button, &border);
|
||||
|
||||
child_allocation.height =
|
||||
allocation->height -
|
||||
(padding.top + padding.bottom) -
|
||||
(border.top + border.bottom);
|
||||
child_allocation.x = allocation->x + border.left;
|
||||
child_allocation.y = allocation->y + border.top;
|
||||
child_allocation.width = allocation->width - border.left - border.right;
|
||||
child_allocation.height = allocation->height - border.top - border.bottom;
|
||||
|
||||
if (gtk_widget_get_can_default (GTK_WIDGET (button)))
|
||||
{
|
||||
child_allocation.x += default_border.left;
|
||||
child_allocation.y += default_border.top;
|
||||
child_allocation.width = child_allocation.width - default_border.left - default_border.right;
|
||||
child_allocation.height = child_allocation.height - default_border.top - default_border.bottom;
|
||||
}
|
||||
|
||||
if (gtk_widget_get_can_focus (GTK_WIDGET (button)))
|
||||
{
|
||||
child_allocation.x += focus_width + focus_pad;
|
||||
child_allocation.y += focus_width + focus_pad;
|
||||
child_allocation.width = child_allocation.width - (focus_width + focus_pad) * 2;
|
||||
child_allocation.height = child_allocation.height - (focus_width + focus_pad) * 2;
|
||||
}
|
||||
baseline = gtk_widget_get_allocated_baseline (widget);
|
||||
if (baseline != -1)
|
||||
baseline -= border.top;
|
||||
|
||||
if (priv->depressed)
|
||||
{
|
||||
gint child_displacement_x;
|
||||
gint child_displacement_y;
|
||||
|
||||
gtk_style_context_get_style (context,
|
||||
gtk_style_context_get_style (gtk_widget_get_style_context (GTK_WIDGET (button)),
|
||||
"child-displacement-x", &child_displacement_x,
|
||||
"child-displacement-y", &child_displacement_y,
|
||||
NULL);
|
||||
child_allocation.x += child_displacement_x;
|
||||
child_allocation.y += child_displacement_y;
|
||||
if (baseline != -1)
|
||||
baseline -= child_displacement_y;
|
||||
}
|
||||
|
||||
child_allocation.width = MAX (1, child_allocation.width);
|
||||
child_allocation.height = MAX (1, child_allocation.height);
|
||||
|
||||
gtk_widget_size_allocate (child, &child_allocation);
|
||||
gtk_widget_size_allocate_with_baseline (child, &child_allocation, baseline);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2062,57 +2096,52 @@ gtk_button_finish_activate (GtkButton *button,
|
||||
static void
|
||||
gtk_button_get_size (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
gint for_size,
|
||||
gint *minimum_size,
|
||||
gint *natural_size)
|
||||
gint *natural_size,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
GtkButton *button = GTK_BUTTON (widget);
|
||||
GtkStyleContext *context;
|
||||
GtkWidget *child;
|
||||
GtkBorder default_border;
|
||||
GtkBorder padding;
|
||||
GtkBorder border;
|
||||
gint focus_width;
|
||||
gint focus_pad;
|
||||
gint minimum, natural;
|
||||
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
|
||||
gtk_button_get_props (button, &default_border, NULL,
|
||||
&padding, &border, NULL);
|
||||
gtk_style_context_get_style (context,
|
||||
"focus-line-width", &focus_width,
|
||||
"focus-padding", &focus_pad,
|
||||
NULL);
|
||||
gtk_button_get_full_border (button, &border);
|
||||
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
minimum = padding.left + padding.right +
|
||||
border.left + border.right;
|
||||
minimum = border.left + border.right;
|
||||
natural = minimum;
|
||||
|
||||
if (gtk_widget_get_can_default (GTK_WIDGET (widget)))
|
||||
minimum += default_border.left + default_border.right;
|
||||
if (for_size >= 0)
|
||||
for_size -= border.top + border.bottom;
|
||||
}
|
||||
else
|
||||
{
|
||||
minimum = padding.top + padding.bottom +
|
||||
border.top + border.bottom;
|
||||
minimum = border.top + border.bottom;
|
||||
natural = minimum;
|
||||
|
||||
if (gtk_widget_get_can_default (GTK_WIDGET (widget)))
|
||||
minimum += default_border.top + default_border.bottom;
|
||||
}
|
||||
|
||||
minimum += 2 * (focus_width + focus_pad);
|
||||
natural = minimum;
|
||||
if (for_size >= 0)
|
||||
for_size -= border.left + border.right;
|
||||
}
|
||||
|
||||
if ((child = gtk_bin_get_child (GTK_BIN (button))) &&
|
||||
gtk_widget_get_visible (child))
|
||||
{
|
||||
gint child_min, child_nat;
|
||||
gint child_min_baseline = -1, child_nat_baseline = -1;
|
||||
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
gtk_widget_get_preferred_width (child, &child_min, &child_nat);
|
||||
else
|
||||
gtk_widget_get_preferred_height (child, &child_min, &child_nat);
|
||||
_gtk_widget_get_preferred_size_for_size (child,
|
||||
orientation,
|
||||
for_size,
|
||||
&child_min, &child_nat,
|
||||
&child_min_baseline, &child_nat_baseline);
|
||||
|
||||
if (minimum_baseline && child_min_baseline >= 0)
|
||||
*minimum_baseline = child_min_baseline + border.top;
|
||||
if (natural_baseline && child_nat_baseline >= 0)
|
||||
*natural_baseline = child_nat_baseline + border.top;
|
||||
|
||||
minimum += child_min;
|
||||
natural += child_nat;
|
||||
@@ -2130,7 +2159,7 @@ gtk_button_get_preferred_width (GtkWidget *widget,
|
||||
gint *minimum_size,
|
||||
gint *natural_size)
|
||||
{
|
||||
gtk_button_get_size (widget, GTK_ORIENTATION_HORIZONTAL, minimum_size, natural_size);
|
||||
gtk_button_get_size (widget, GTK_ORIENTATION_HORIZONTAL, -1, minimum_size, natural_size, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2138,7 +2167,36 @@ gtk_button_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum_size,
|
||||
gint *natural_size)
|
||||
{
|
||||
gtk_button_get_size (widget, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size);
|
||||
gtk_button_get_size (widget, GTK_ORIENTATION_VERTICAL, -1, minimum_size, natural_size, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_button_get_preferred_width_for_height (GtkWidget *widget,
|
||||
gint for_size,
|
||||
gint *minimum_size,
|
||||
gint *natural_size)
|
||||
{
|
||||
gtk_button_get_size (widget, GTK_ORIENTATION_HORIZONTAL, for_size, minimum_size, natural_size, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_button_get_preferred_height_for_width (GtkWidget *widget,
|
||||
gint for_size,
|
||||
gint *minimum_size,
|
||||
gint *natural_size)
|
||||
{
|
||||
gtk_button_get_size (widget, GTK_ORIENTATION_VERTICAL, for_size, minimum_size, natural_size, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_button_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum_size,
|
||||
gint *natural_size,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
gtk_button_get_size (widget, GTK_ORIENTATION_VERTICAL, width, minimum_size, natural_size, minimum_baseline, natural_baseline);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -39,6 +39,9 @@ struct _GtkButtonPrivate
|
||||
gfloat xalign;
|
||||
gfloat yalign;
|
||||
|
||||
/* This is only used by checkbox and subclasses */
|
||||
gfloat baseline_align;
|
||||
|
||||
guint activate_timeout;
|
||||
guint32 grab_time;
|
||||
|
||||
|
||||
@@ -239,10 +239,6 @@ G_DEFINE_TYPE_WITH_CODE (GtkCellAreaBox, gtk_cell_area_box, GTK_TYPE_CELL_AREA,
|
||||
gtk_cell_area_box_cell_layout_init)
|
||||
G_IMPLEMENT_INTERFACE (GTK_TYPE_ORIENTABLE, NULL));
|
||||
|
||||
#define OPPOSITE_ORIENTATION(orientation) \
|
||||
((orientation) == GTK_ORIENTATION_HORIZONTAL ? \
|
||||
GTK_ORIENTATION_VERTICAL : GTK_ORIENTATION_HORIZONTAL)
|
||||
|
||||
static void
|
||||
gtk_cell_area_box_init (GtkCellAreaBox *box)
|
||||
{
|
||||
|
||||
@@ -812,7 +812,7 @@ cell_packing_end_element (GMarkupParseContext *context,
|
||||
/* translate the string */
|
||||
if (parser_data->string->len && parser_data->translatable)
|
||||
{
|
||||
gchar *translated;
|
||||
const gchar *translated;
|
||||
const gchar* domain;
|
||||
|
||||
domain = gtk_builder_get_translation_domain (parser_data->builder);
|
||||
|
||||
@@ -58,6 +58,12 @@ static void gtk_check_button_get_preferred_width (GtkWidget *widget,
|
||||
static void gtk_check_button_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural);
|
||||
static void gtk_check_button_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum,
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline);
|
||||
static void gtk_check_button_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *allocation);
|
||||
static gboolean gtk_check_button_draw (GtkWidget *widget,
|
||||
@@ -80,6 +86,7 @@ gtk_check_button_class_init (GtkCheckButtonClass *class)
|
||||
|
||||
widget_class->get_preferred_width = gtk_check_button_get_preferred_width;
|
||||
widget_class->get_preferred_height = gtk_check_button_get_preferred_height;
|
||||
widget_class->get_preferred_height_and_baseline_for_width = gtk_check_button_get_preferred_height_and_baseline_for_width;
|
||||
widget_class->size_allocate = gtk_check_button_size_allocate;
|
||||
widget_class->draw = gtk_check_button_draw;
|
||||
|
||||
@@ -287,9 +294,12 @@ gtk_check_button_get_preferred_width (GtkWidget *widget,
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_check_button_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
gtk_check_button_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum,
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
GtkToggleButton *toggle_button = GTK_TOGGLE_BUTTON (widget);
|
||||
|
||||
@@ -301,6 +311,7 @@ gtk_check_button_get_preferred_height (GtkWidget *widget,
|
||||
gint indicator_spacing;
|
||||
gint focus_width;
|
||||
gint focus_pad;
|
||||
gint old_minimum, old_natural;
|
||||
guint border_width;
|
||||
|
||||
border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
|
||||
@@ -320,29 +331,61 @@ gtk_check_button_get_preferred_height (GtkWidget *widget,
|
||||
if (child && gtk_widget_get_visible (child))
|
||||
{
|
||||
gint child_min, child_nat;
|
||||
gint child_min_baseline = -1, child_nat_baseline = -1;
|
||||
|
||||
gtk_widget_get_preferred_height (child, &child_min, &child_nat);
|
||||
gtk_widget_get_preferred_height_and_baseline_for_width (child, -1,
|
||||
&child_min, &child_nat,
|
||||
&child_min_baseline, &child_nat_baseline);
|
||||
|
||||
if (minimum_baseline && child_min_baseline >= 0)
|
||||
*minimum_baseline = child_min_baseline + border_width;
|
||||
if (natural_baseline && child_nat_baseline >= 0)
|
||||
*natural_baseline = child_nat_baseline + border_width;
|
||||
|
||||
*minimum += child_min;
|
||||
*natural += child_nat;
|
||||
|
||||
}
|
||||
|
||||
old_minimum = *minimum;
|
||||
old_natural = *natural;
|
||||
|
||||
temp = indicator_size + indicator_spacing * 2;
|
||||
*minimum = MAX (*minimum, temp) + 2 * (focus_width + focus_pad);
|
||||
*natural = MAX (*natural, temp) + 2 * (focus_width + focus_pad);
|
||||
|
||||
if (minimum_baseline && *minimum_baseline != -1)
|
||||
minimum_baseline += (*minimum - old_minimum) / 2;
|
||||
if (natural_baseline && *natural_baseline != -1)
|
||||
natural_baseline += (*natural - old_natural) / 2;
|
||||
}
|
||||
else
|
||||
GTK_WIDGET_CLASS (gtk_check_button_parent_class)->get_preferred_height (widget, minimum, natural);
|
||||
GTK_WIDGET_CLASS (gtk_check_button_parent_class)->get_preferred_height_and_baseline_for_width (widget, width,
|
||||
minimum, natural,
|
||||
minimum_baseline, natural_baseline);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_check_button_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
{
|
||||
gtk_check_button_get_preferred_height_and_baseline_for_width (widget, -1,
|
||||
minimum, natural,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_check_button_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *allocation)
|
||||
{
|
||||
PangoContext *pango_context;
|
||||
PangoFontMetrics *metrics;
|
||||
GtkCheckButton *check_button;
|
||||
GtkToggleButton *toggle_button;
|
||||
GtkButton *button;
|
||||
GtkAllocation child_allocation;
|
||||
gint baseline;
|
||||
|
||||
button = GTK_BUTTON (widget);
|
||||
check_button = GTK_CHECK_BUTTON (widget);
|
||||
@@ -389,8 +432,21 @@ gtk_check_button_size_allocate (GtkWidget *widget,
|
||||
child_allocation.x = allocation->x + allocation->width
|
||||
- (child_allocation.x - allocation->x + child_allocation.width);
|
||||
|
||||
gtk_widget_size_allocate (child, &child_allocation);
|
||||
baseline = gtk_widget_get_allocated_baseline (widget);
|
||||
if (baseline != -1)
|
||||
baseline -= child_allocation.y - allocation->y;
|
||||
gtk_widget_size_allocate_with_baseline (child, &child_allocation, baseline);
|
||||
}
|
||||
|
||||
pango_context = gtk_widget_get_pango_context (widget);
|
||||
metrics = pango_context_get_metrics (pango_context,
|
||||
pango_context_get_font_description (pango_context),
|
||||
pango_context_get_language (pango_context));
|
||||
button->priv->baseline_align =
|
||||
(double)pango_font_metrics_get_ascent (metrics) /
|
||||
(pango_font_metrics_get_ascent (metrics) + pango_font_metrics_get_descent (metrics));
|
||||
pango_font_metrics_unref (metrics);
|
||||
|
||||
}
|
||||
else
|
||||
GTK_WIDGET_CLASS (gtk_check_button_parent_class)->size_allocate (widget, allocation);
|
||||
@@ -448,6 +504,7 @@ gtk_real_check_button_draw_indicator (GtkCheckButton *check_button,
|
||||
gint indicator_spacing;
|
||||
gint focus_width;
|
||||
gint focus_pad;
|
||||
gint baseline;
|
||||
guint border_width;
|
||||
gboolean interior_focus;
|
||||
GtkAllocation allocation;
|
||||
@@ -458,6 +515,7 @@ gtk_real_check_button_draw_indicator (GtkCheckButton *check_button,
|
||||
toggle_button = GTK_TOGGLE_BUTTON (check_button);
|
||||
|
||||
gtk_widget_get_allocation (widget, &allocation);
|
||||
baseline = gtk_widget_get_allocated_baseline (widget);
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
state = gtk_widget_get_state_flags (widget);
|
||||
|
||||
@@ -472,7 +530,11 @@ gtk_real_check_button_draw_indicator (GtkCheckButton *check_button,
|
||||
border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
|
||||
|
||||
x = indicator_spacing + border_width;
|
||||
y = (allocation.height - indicator_size) / 2;
|
||||
if (baseline == -1)
|
||||
y = (allocation.height - indicator_size) / 2;
|
||||
else
|
||||
y = CLAMP (baseline - indicator_size * button->priv->baseline_align,
|
||||
0, allocation.height - indicator_size);
|
||||
|
||||
child = gtk_bin_get_child (GTK_BIN (check_button));
|
||||
if (!interior_focus || !(child && gtk_widget_get_visible (child)))
|
||||
|
||||
@@ -234,7 +234,7 @@ item_end_element (GMarkupParseContext *context,
|
||||
{
|
||||
if (data->translatable)
|
||||
{
|
||||
gchar *translated;
|
||||
const gchar *translated;
|
||||
|
||||
/* FIXME: This will not use the domain set in the .ui file,
|
||||
* since the parser is not telling the builder about the domain.
|
||||
|
||||
@@ -309,12 +309,17 @@ static void gtk_container_adjust_size_request (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
gint *minimum_size,
|
||||
gint *natural_size);
|
||||
static void gtk_container_adjust_baseline_request (GtkWidget *widget,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline);
|
||||
static void gtk_container_adjust_size_allocation (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
gint *minimum_size,
|
||||
gint *natural_size,
|
||||
gint *allocated_pos,
|
||||
gint *allocated_size);
|
||||
static void gtk_container_adjust_baseline_allocation (GtkWidget *widget,
|
||||
gint *baseline);
|
||||
static GtkSizeRequestMode gtk_container_get_request_mode (GtkWidget *widget);
|
||||
|
||||
static gchar* gtk_container_child_default_composite_name (GtkContainer *container,
|
||||
@@ -444,7 +449,9 @@ gtk_container_class_init (GtkContainerClass *class)
|
||||
widget_class->focus = gtk_container_focus;
|
||||
|
||||
widget_class->adjust_size_request = gtk_container_adjust_size_request;
|
||||
widget_class->adjust_baseline_request = gtk_container_adjust_baseline_request;
|
||||
widget_class->adjust_size_allocation = gtk_container_adjust_size_allocation;
|
||||
widget_class->adjust_baseline_allocation = gtk_container_adjust_baseline_allocation;
|
||||
widget_class->get_request_mode = gtk_container_get_request_mode;
|
||||
|
||||
class->add = gtk_container_add_unimplemented;
|
||||
@@ -657,8 +664,8 @@ attributes_end_element (GMarkupParseContext *context,
|
||||
/* translate the string */
|
||||
if (parser_data->string->len && parser_data->translatable)
|
||||
{
|
||||
gchar *translated;
|
||||
const gchar* domain;
|
||||
const gchar *translated;
|
||||
const gchar *domain;
|
||||
|
||||
domain = gtk_builder_get_translation_domain (parser_data->builder);
|
||||
|
||||
@@ -1917,6 +1924,28 @@ gtk_container_adjust_size_request (GtkWidget *widget,
|
||||
minimum_size, natural_size);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_container_adjust_baseline_request (GtkWidget *widget,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
GtkContainer *container;
|
||||
|
||||
container = GTK_CONTAINER (widget);
|
||||
|
||||
if (GTK_CONTAINER_GET_CLASS (widget)->_handle_border_width)
|
||||
{
|
||||
int border_width;
|
||||
|
||||
border_width = container->priv->border_width;
|
||||
|
||||
*minimum_baseline += border_width;
|
||||
*natural_baseline += border_width;
|
||||
}
|
||||
|
||||
parent_class->adjust_baseline_request (widget, minimum_baseline, natural_baseline);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_container_adjust_size_allocation (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
@@ -1952,6 +1981,27 @@ gtk_container_adjust_size_allocation (GtkWidget *widget,
|
||||
allocated_size);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_container_adjust_baseline_allocation (GtkWidget *widget,
|
||||
gint *baseline)
|
||||
{
|
||||
GtkContainer *container;
|
||||
int border_width;
|
||||
|
||||
container = GTK_CONTAINER (widget);
|
||||
|
||||
if (GTK_CONTAINER_GET_CLASS (widget)->_handle_border_width)
|
||||
{
|
||||
border_width = container->priv->border_width;
|
||||
|
||||
if (*baseline >= 0)
|
||||
*baseline -= border_width;
|
||||
}
|
||||
|
||||
parent_class->adjust_baseline_allocation (widget, baseline);
|
||||
}
|
||||
|
||||
|
||||
typedef struct {
|
||||
gint hfw;
|
||||
gint wfh;
|
||||
@@ -3315,7 +3365,7 @@ gtk_container_propagate_draw (GtkContainer *container,
|
||||
{
|
||||
GdkEventExpose *event;
|
||||
GtkAllocation allocation;
|
||||
GdkWindow *window, *w;
|
||||
GdkWindow *window, *w, *event_window, *child_in_window;
|
||||
int x, y;
|
||||
|
||||
g_return_if_fail (GTK_IS_CONTAINER (container));
|
||||
@@ -3324,13 +3374,26 @@ gtk_container_propagate_draw (GtkContainer *container,
|
||||
|
||||
g_assert (gtk_widget_get_parent (child) == GTK_WIDGET (container));
|
||||
|
||||
if (!gtk_widget_is_drawable (child))
|
||||
return;
|
||||
|
||||
/* Only propagate to native child window if we're not handling
|
||||
an expose (i.e. in a pure gtk_widget_draw() call */
|
||||
event = _gtk_cairo_get_event (cr);
|
||||
if (event)
|
||||
{
|
||||
if (gtk_widget_get_has_window (child) ||
|
||||
gtk_widget_get_window (child) != event->window)
|
||||
return;
|
||||
}
|
||||
if (event &&
|
||||
(gtk_widget_get_has_window (child) &&
|
||||
gdk_window_has_native (gtk_widget_get_window (child))))
|
||||
return;
|
||||
|
||||
/* Never propagate to a child window when exposing a window
|
||||
that is not the one the child widget is in. */
|
||||
event_window = _gtk_cairo_get_event_window (cr);
|
||||
if (gtk_widget_get_has_window (child))
|
||||
child_in_window = gdk_window_get_parent (gtk_widget_get_window (child));
|
||||
else
|
||||
child_in_window = gtk_widget_get_window (child);
|
||||
if (event_window != NULL && child_in_window != event_window)
|
||||
return;
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
@@ -3372,7 +3435,7 @@ gtk_container_propagate_draw (GtkContainer *container,
|
||||
|
||||
cairo_translate (cr, x, y);
|
||||
|
||||
_gtk_widget_draw_internal (child, cr, TRUE);
|
||||
_gtk_widget_draw (child, cr);
|
||||
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
@@ -300,3 +300,37 @@ _gtk_css_shadows_value_paint_box (const GtkCssValue *shadows,
|
||||
_gtk_css_shadow_value_paint_box (shadows->values[i], cr, padding_box);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_css_shadows_value_get_extents (const GtkCssValue *shadows,
|
||||
GtkBorder *border)
|
||||
{
|
||||
guint i;
|
||||
GtkBorder b = { 0 };
|
||||
const GtkCssValue *shadow;
|
||||
gdouble hoffset, voffset, spread, radius;
|
||||
|
||||
g_return_if_fail (shadows->class == >K_CSS_VALUE_SHADOWS);
|
||||
|
||||
for (i = 0; i < shadows->len; i++)
|
||||
{
|
||||
shadow = shadows->values[i];
|
||||
|
||||
if (_gtk_css_shadow_value_get_inset (shadow))
|
||||
continue;
|
||||
|
||||
_gtk_css_shadow_value_get_geometry (shadow,
|
||||
&hoffset, &voffset,
|
||||
&radius, &spread);
|
||||
|
||||
b.top = MAX (0, radius + spread - voffset);
|
||||
b.right = MAX (0, radius + spread + hoffset);
|
||||
b.bottom = MAX (0, radius + spread + voffset);
|
||||
b.left = MAX (0, radius + spread - hoffset);
|
||||
|
||||
border->top = MAX (border->top, b.top);
|
||||
border->right = MAX (border->right, b.right);
|
||||
border->bottom = MAX (border->bottom, b.bottom);
|
||||
border->left = MAX (border->left, b.left);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,6 +49,9 @@ void _gtk_css_shadows_value_paint_box (const GtkCssValue
|
||||
const GtkRoundedBox *padding_box,
|
||||
gboolean inset);
|
||||
|
||||
void _gtk_css_shadows_value_get_extents (const GtkCssValue *shadows,
|
||||
GtkBorder *border);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_CSS_SHADOWS_VALUE_H__ */
|
||||
|
||||
@@ -453,6 +453,26 @@ _gtk_css_shadow_value_get_inset (const GtkCssValue *shadow)
|
||||
return shadow->inset;
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_css_shadow_value_get_geometry (const GtkCssValue *shadow,
|
||||
gdouble *hoffset,
|
||||
gdouble *voffset,
|
||||
gdouble *radius,
|
||||
gdouble *spread)
|
||||
{
|
||||
g_return_if_fail (shadow->class == >K_CSS_VALUE_SHADOW);
|
||||
|
||||
if (hoffset != NULL)
|
||||
*hoffset = _gtk_css_number_value_get (shadow->hoffset, 0);
|
||||
if (voffset != NULL)
|
||||
*voffset = _gtk_css_number_value_get (shadow->voffset, 0);
|
||||
|
||||
if (radius != NULL)
|
||||
*radius = _gtk_css_number_value_get (shadow->radius, 0);
|
||||
if (spread != NULL)
|
||||
*spread = _gtk_css_number_value_get (shadow->spread, 0);
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_css_shadow_value_paint_box (const GtkCssValue *shadow,
|
||||
cairo_t *cr,
|
||||
|
||||
@@ -36,6 +36,12 @@ GtkCssValue * _gtk_css_shadow_value_parse (GtkCssParser
|
||||
|
||||
gboolean _gtk_css_shadow_value_get_inset (const GtkCssValue *shadow);
|
||||
|
||||
void _gtk_css_shadow_value_get_geometry (const GtkCssValue *shadow,
|
||||
gdouble *hoffset,
|
||||
gdouble *voffset,
|
||||
gdouble *radius,
|
||||
gdouble *spread);
|
||||
|
||||
void _gtk_css_shadow_value_paint_layout (const GtkCssValue *shadow,
|
||||
cairo_t *cr,
|
||||
PangoLayout *layout);
|
||||
|
||||
@@ -47,7 +47,9 @@ typedef enum {
|
||||
GTK_DEBUG_PRINTING = 1 << 10,
|
||||
GTK_DEBUG_BUILDER = 1 << 11,
|
||||
GTK_DEBUG_SIZE_REQUEST = 1 << 12,
|
||||
GTK_DEBUG_NO_CSS_CACHE = 1 << 13
|
||||
GTK_DEBUG_NO_CSS_CACHE = 1 << 13,
|
||||
GTK_DEBUG_BASELINES = 1 << 14,
|
||||
GTK_DEBUG_PIXEL_CACHE = 1 << 15
|
||||
} GtkDebugFlag;
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
|
||||
@@ -744,6 +744,7 @@ gtk_dialog_add_button (GtkDialog *dialog,
|
||||
button = gtk_button_new_from_stock (button_text);
|
||||
|
||||
gtk_widget_set_can_default (button, TRUE);
|
||||
gtk_widget_set_valign (button, GTK_ALIGN_BASELINE);
|
||||
|
||||
gtk_widget_show (button);
|
||||
|
||||
|
||||
@@ -367,6 +367,12 @@ static void gtk_entry_get_preferred_width (GtkWidget *widget,
|
||||
static void gtk_entry_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural);
|
||||
static void gtk_entry_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum_height,
|
||||
gint *natural_height,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline);
|
||||
static void gtk_entry_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *allocation);
|
||||
static void gtk_entry_draw_frame (GtkWidget *widget,
|
||||
@@ -682,6 +688,7 @@ gtk_entry_class_init (GtkEntryClass *class)
|
||||
widget_class->unrealize = gtk_entry_unrealize;
|
||||
widget_class->get_preferred_width = gtk_entry_get_preferred_width;
|
||||
widget_class->get_preferred_height = gtk_entry_get_preferred_height;
|
||||
widget_class->get_preferred_height_and_baseline_for_width = gtk_entry_get_preferred_height_and_baseline_for_width;
|
||||
widget_class->size_allocate = gtk_entry_size_allocate;
|
||||
widget_class->draw = gtk_entry_draw;
|
||||
widget_class->enter_notify_event = gtk_entry_enter_notify;
|
||||
@@ -3305,16 +3312,19 @@ gtk_entry_get_preferred_width (GtkWidget *widget,
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_entry_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
gtk_entry_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum,
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
GtkEntry *entry = GTK_ENTRY (widget);
|
||||
GtkEntryPrivate *priv = entry->priv;
|
||||
PangoFontMetrics *metrics;
|
||||
GtkBorder borders;
|
||||
PangoContext *context;
|
||||
gint height;
|
||||
gint height, baseline;
|
||||
PangoLayout *layout;
|
||||
|
||||
layout = gtk_entry_ensure_layout (entry, TRUE);
|
||||
@@ -3333,8 +3343,27 @@ gtk_entry_get_preferred_height (GtkWidget *widget,
|
||||
|
||||
height += borders.top + borders.bottom;
|
||||
|
||||
baseline = pango_layout_get_baseline (layout) / PANGO_SCALE;
|
||||
baseline += borders.top;
|
||||
|
||||
*minimum = height;
|
||||
*natural = height;
|
||||
if (minimum_baseline)
|
||||
*minimum_baseline = baseline;
|
||||
if (natural_baseline)
|
||||
*natural_baseline = baseline;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_entry_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
{
|
||||
gtk_entry_get_preferred_height_and_baseline_for_width (widget,
|
||||
-1,
|
||||
minimum,
|
||||
natural,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -3452,13 +3481,17 @@ gtk_entry_get_frame_size (GtkEntry *entry,
|
||||
GtkAllocation allocation;
|
||||
GtkRequisition requisition;
|
||||
GtkWidget *widget = GTK_WIDGET (entry);
|
||||
gint area_height, y_pos;
|
||||
gint baseline;
|
||||
gint req_height;
|
||||
GtkBorder borders;
|
||||
|
||||
gtk_widget_get_preferred_size (widget, &requisition, NULL);
|
||||
|
||||
req_height = requisition.height - gtk_widget_get_margin_top (widget) - gtk_widget_get_margin_bottom (widget);
|
||||
|
||||
gtk_widget_get_allocation (widget, &allocation);
|
||||
baseline = gtk_widget_get_allocated_baseline (widget);
|
||||
|
||||
if (x)
|
||||
*x = allocation.x;
|
||||
@@ -3468,7 +3501,17 @@ gtk_entry_get_frame_size (GtkEntry *entry,
|
||||
if (priv->is_cell_renderer)
|
||||
*y = 0;
|
||||
else
|
||||
*y = (allocation.height - req_height) / 2;
|
||||
{
|
||||
if (baseline == -1)
|
||||
*y = (allocation.height - req_height) / 2;
|
||||
else
|
||||
{
|
||||
_gtk_entry_get_borders (entry, &borders);
|
||||
area_height = req_height - borders.top - borders.bottom;
|
||||
y_pos = ((area_height * PANGO_SCALE - priv->ascent - priv->descent) / 2 + priv->ascent) / PANGO_SCALE;
|
||||
*y = baseline - y_pos - borders.top;
|
||||
}
|
||||
}
|
||||
|
||||
*y += allocation.y;
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@ G_BEGIN_DECLS
|
||||
* or top
|
||||
* @GTK_ALIGN_CENTER: center natural width of widget inside the
|
||||
* allocation
|
||||
* @GTK_ALIGN_BASELINE: align the widget according to the baseline. Since 3.10.
|
||||
*
|
||||
* Controls how a widget deals with extra space in a single (x or y)
|
||||
* dimension.
|
||||
@@ -64,13 +65,18 @@ G_BEGIN_DECLS
|
||||
*
|
||||
* Note that in horizontal context @GTK_ALIGN_START and @GTK_ALIGN_END
|
||||
* are interpreted relative to text direction.
|
||||
*
|
||||
* GTK_ALIGN_BASELINE support for it is optional for containers and widgets, and
|
||||
* it is only supported for vertical alignment. When its not supported by
|
||||
* a child or a container it is treated as @GTK_ALIGN_FILL.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
GTK_ALIGN_FILL,
|
||||
GTK_ALIGN_START,
|
||||
GTK_ALIGN_END,
|
||||
GTK_ALIGN_CENTER
|
||||
GTK_ALIGN_CENTER,
|
||||
GTK_ALIGN_BASELINE
|
||||
} GtkAlign;
|
||||
|
||||
|
||||
@@ -125,6 +131,28 @@ typedef enum
|
||||
GTK_FILL = 1 << 2
|
||||
} GtkAttachOptions;
|
||||
|
||||
/**
|
||||
* GtkBaselinePosition:
|
||||
* @GTK_BASELINE_POSITION_TOP: Align the baseline at the top
|
||||
* @GTK_BASELINE_POSITION_CENTER: Center the baseline
|
||||
* @GTK_BASELINE_POSITION_BOTTOM: Align the baseline at the bottom
|
||||
*
|
||||
* Whenever a container has some form of natural row it may align
|
||||
* children in that row along a common typographical baseline. If
|
||||
* the amount of verical space in the row is taller than the total
|
||||
* requested height of the baseline-aligned children then it can use a
|
||||
* #GtkBaselinePosition to select where to put the baseline inside the
|
||||
* extra availible space.
|
||||
*
|
||||
* Since: 3.10
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
GTK_BASELINE_POSITION_TOP,
|
||||
GTK_BASELINE_POSITION_CENTER,
|
||||
GTK_BASELINE_POSITION_BOTTOM
|
||||
} GtkBaselinePosition;
|
||||
|
||||
/**
|
||||
* GtkButtonBoxStyle:
|
||||
* @GTK_BUTTONBOX_DEFAULT_STYLE: Default packing.
|
||||
|
||||
@@ -65,6 +65,12 @@ static void gtk_event_box_get_preferred_width (GtkWidget *widget,
|
||||
static void gtk_event_box_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural);
|
||||
static void gtk_event_box_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum,
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline);
|
||||
static void gtk_event_box_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *allocation);
|
||||
static gboolean gtk_event_box_draw (GtkWidget *widget,
|
||||
@@ -96,6 +102,7 @@ gtk_event_box_class_init (GtkEventBoxClass *class)
|
||||
widget_class->unmap = gtk_event_box_unmap;
|
||||
widget_class->get_preferred_width = gtk_event_box_get_preferred_width;
|
||||
widget_class->get_preferred_height = gtk_event_box_get_preferred_height;
|
||||
widget_class->get_preferred_height_and_baseline_for_width = gtk_event_box_get_preferred_height_and_baseline_for_width;
|
||||
widget_class->size_allocate = gtk_event_box_size_allocate;
|
||||
widget_class->draw = gtk_event_box_draw;
|
||||
|
||||
@@ -515,9 +522,12 @@ gtk_event_box_get_preferred_width (GtkWidget *widget,
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_event_box_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
gtk_event_box_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum,
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
GtkBin *bin = GTK_BIN (widget);
|
||||
GtkWidget *child;
|
||||
@@ -528,9 +538,30 @@ gtk_event_box_get_preferred_height (GtkWidget *widget,
|
||||
if (natural)
|
||||
*natural = 0;
|
||||
|
||||
if (minimum_baseline)
|
||||
*minimum_baseline = -1;
|
||||
|
||||
if (natural_baseline)
|
||||
*natural_baseline = -1;
|
||||
|
||||
child = gtk_bin_get_child (bin);
|
||||
if (child && gtk_widget_get_visible (child))
|
||||
gtk_widget_get_preferred_height (child, minimum, natural);
|
||||
gtk_widget_get_preferred_height_and_baseline_for_width (child,
|
||||
-1,
|
||||
minimum,
|
||||
natural,
|
||||
minimum_baseline,
|
||||
natural_baseline);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_event_box_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
{
|
||||
gtk_event_box_get_preferred_height_and_baseline_for_width (widget, -1,
|
||||
minimum, natural,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -539,6 +570,7 @@ gtk_event_box_size_allocate (GtkWidget *widget,
|
||||
{
|
||||
GtkBin *bin;
|
||||
GtkAllocation child_allocation;
|
||||
gint baseline;
|
||||
GtkEventBoxPrivate *priv;
|
||||
GtkWidget *child;
|
||||
|
||||
@@ -578,9 +610,10 @@ gtk_event_box_size_allocate (GtkWidget *widget,
|
||||
child_allocation.height);
|
||||
}
|
||||
|
||||
baseline = gtk_widget_get_allocated_baseline (widget);
|
||||
child = gtk_bin_get_child (bin);
|
||||
if (child)
|
||||
gtk_widget_size_allocate (child, &child_allocation);
|
||||
gtk_widget_size_allocate_with_baseline (child, &child_allocation, baseline);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
||||
@@ -290,7 +290,7 @@
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="list_mtime_column">
|
||||
<property name="resizable">True</property>
|
||||
<property name="title" translatable="yes">Modifed</property>
|
||||
<property name="title" translatable="yes">Modified</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="list_mtime_renderer"/>
|
||||
</child>
|
||||
|
||||
@@ -109,6 +109,18 @@ gboolean gtk_grid_get_column_homogeneous (GtkGrid *grid);
|
||||
void gtk_grid_set_column_spacing (GtkGrid *grid,
|
||||
guint spacing);
|
||||
guint gtk_grid_get_column_spacing (GtkGrid *grid);
|
||||
GDK_AVAILABLE_IN_3_10
|
||||
void gtk_grid_set_row_baseline_position (GtkGrid *grid,
|
||||
gint row,
|
||||
GtkBaselinePosition pos);
|
||||
GDK_AVAILABLE_IN_3_10
|
||||
GtkBaselinePosition gtk_grid_get_row_baseline_position (GtkGrid *grid,
|
||||
gint row);
|
||||
GDK_AVAILABLE_IN_3_10
|
||||
void gtk_grid_set_baseline_row (GtkGrid *grid,
|
||||
gint row);
|
||||
GDK_AVAILABLE_IN_3_10
|
||||
gint gtk_grid_get_baseline_row (GtkGrid *grid);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@@ -140,6 +140,8 @@ struct _GtkImagePrivate
|
||||
|
||||
gchar *filename; /* Only used with GTK_IMAGE_ANIMATION, GTK_IMAGE_PIXBUF */
|
||||
gchar *resource_path; /* Only used with GTK_IMAGE_PIXBUF */
|
||||
|
||||
float baseline_align;
|
||||
};
|
||||
|
||||
|
||||
@@ -154,6 +156,12 @@ static void gtk_image_get_preferred_width (GtkWidget *widget,
|
||||
static void gtk_image_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural);
|
||||
static void gtk_image_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum,
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline);
|
||||
|
||||
static void gtk_image_style_updated (GtkWidget *widget);
|
||||
static void gtk_image_screen_changed (GtkWidget *widget,
|
||||
@@ -207,6 +215,7 @@ gtk_image_class_init (GtkImageClass *class)
|
||||
widget_class->draw = gtk_image_draw;
|
||||
widget_class->get_preferred_width = gtk_image_get_preferred_width;
|
||||
widget_class->get_preferred_height = gtk_image_get_preferred_height;
|
||||
widget_class->get_preferred_height_and_baseline_for_width = gtk_image_get_preferred_height_and_baseline_for_width;
|
||||
widget_class->unmap = gtk_image_unmap;
|
||||
widget_class->unrealize = gtk_image_unrealize;
|
||||
widget_class->style_updated = gtk_image_style_updated;
|
||||
@@ -1393,6 +1402,28 @@ gtk_image_get_preferred_size (GtkImage *image,
|
||||
*height_out = height;
|
||||
}
|
||||
|
||||
static float
|
||||
gtk_image_get_baseline_align (GtkImage *image)
|
||||
{
|
||||
PangoContext *pango_context;
|
||||
PangoFontMetrics *metrics;
|
||||
|
||||
if (image->priv->baseline_align == 0.0)
|
||||
{
|
||||
pango_context = gtk_widget_get_pango_context (GTK_WIDGET (image));
|
||||
metrics = pango_context_get_metrics (pango_context,
|
||||
pango_context_get_font_description (pango_context),
|
||||
pango_context_get_language (pango_context));
|
||||
image->priv->baseline_align =
|
||||
(float)pango_font_metrics_get_ascent (metrics) /
|
||||
(pango_font_metrics_get_ascent (metrics) + pango_font_metrics_get_descent (metrics));
|
||||
|
||||
pango_font_metrics_unref (metrics);
|
||||
}
|
||||
|
||||
return image->priv->baseline_align;
|
||||
}
|
||||
|
||||
static gint
|
||||
gtk_image_draw (GtkWidget *widget,
|
||||
cairo_t *cr)
|
||||
@@ -1401,7 +1432,7 @@ gtk_image_draw (GtkWidget *widget,
|
||||
GtkImagePrivate *priv;
|
||||
GtkMisc *misc;
|
||||
GtkStyleContext *context;
|
||||
gint x, y, width, height;
|
||||
gint x, y, width, height, baseline;
|
||||
gfloat xalign, yalign;
|
||||
GtkBorder border;
|
||||
|
||||
@@ -1427,8 +1458,14 @@ gtk_image_draw (GtkWidget *widget,
|
||||
if (gtk_widget_get_direction (widget) != GTK_TEXT_DIR_LTR)
|
||||
xalign = 1.0 - xalign;
|
||||
|
||||
baseline = gtk_widget_get_allocated_baseline (widget);
|
||||
|
||||
x = floor ((gtk_widget_get_allocated_width (widget) - width) * xalign) + border.left;
|
||||
y = floor ((gtk_widget_get_allocated_height (widget) - height) * yalign) + border.top;
|
||||
if (baseline == -1)
|
||||
y = floor ((gtk_widget_get_allocated_height (widget) - height) * yalign) + border.top;
|
||||
else
|
||||
y = CLAMP (baseline - height * gtk_image_get_baseline_align (image),
|
||||
border.top, gtk_widget_get_allocated_height (widget) - height);
|
||||
|
||||
if (gtk_image_get_storage_type (image) == GTK_IMAGE_ANIMATION)
|
||||
{
|
||||
@@ -1535,15 +1572,37 @@ gtk_image_get_preferred_width (GtkWidget *widget,
|
||||
*minimum = *natural = width;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_image_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum,
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
gint height;
|
||||
float baseline_align;
|
||||
|
||||
gtk_image_get_preferred_size (GTK_IMAGE (widget), NULL, &height);
|
||||
*minimum = *natural = height;
|
||||
|
||||
if (minimum_baseline || natural_baseline)
|
||||
{
|
||||
baseline_align = gtk_image_get_baseline_align (GTK_IMAGE (widget));
|
||||
if (minimum_baseline)
|
||||
*minimum_baseline = height * baseline_align;
|
||||
if (natural_baseline)
|
||||
*natural_baseline = height * baseline_align;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_image_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
{
|
||||
gint height;
|
||||
|
||||
gtk_image_get_preferred_size (GTK_IMAGE (widget), NULL, &height);
|
||||
*minimum = *natural = height;
|
||||
gtk_image_get_preferred_height_and_baseline_for_width (widget, -1, minimum, natural,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1558,9 +1617,13 @@ icon_theme_changed (GtkImage *image)
|
||||
static void
|
||||
gtk_image_style_updated (GtkWidget *widget)
|
||||
{
|
||||
GtkImage *image = GTK_IMAGE (widget);
|
||||
GtkImagePrivate *priv = image->priv;
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_image_parent_class)->style_updated (widget);
|
||||
|
||||
icon_theme_changed (GTK_IMAGE (widget));
|
||||
icon_theme_changed (image);
|
||||
priv->baseline_align = 0.0;
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -519,6 +519,12 @@ static void gtk_label_get_preferred_height_for_width (GtkWidget
|
||||
gint width,
|
||||
gint *minimum_height,
|
||||
gint *natural_height);
|
||||
static void gtk_label_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum_height,
|
||||
gint *natural_height,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline);
|
||||
|
||||
static GtkBuildableIface *buildable_parent_iface = NULL;
|
||||
|
||||
@@ -585,6 +591,7 @@ gtk_label_class_init (GtkLabelClass *class)
|
||||
widget_class->get_preferred_height = gtk_label_get_preferred_height;
|
||||
widget_class->get_preferred_width_for_height = gtk_label_get_preferred_width_for_height;
|
||||
widget_class->get_preferred_height_for_width = gtk_label_get_preferred_height_for_width;
|
||||
widget_class->get_preferred_height_and_baseline_for_width = gtk_label_get_preferred_height_and_baseline_for_width;
|
||||
|
||||
class->move_cursor = gtk_label_move_cursor;
|
||||
class->copy_clipboard = gtk_label_copy_clipboard;
|
||||
@@ -3462,15 +3469,18 @@ gtk_label_get_request_mode (GtkWidget *widget)
|
||||
return GTK_SIZE_REQUEST_CONSTANT_SIZE;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
get_size_for_allocation (GtkLabel *label,
|
||||
GtkOrientation orientation,
|
||||
gint allocation,
|
||||
gint *minimum_size,
|
||||
gint *natural_size)
|
||||
gint *natural_size,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
PangoLayout *layout;
|
||||
gint text_height;
|
||||
gint text_height, baseline;
|
||||
|
||||
layout = gtk_label_get_measuring_layout (label, NULL, allocation * PANGO_SCALE);
|
||||
|
||||
@@ -3482,6 +3492,16 @@ get_size_for_allocation (GtkLabel *label,
|
||||
if (natural_size)
|
||||
*natural_size = text_height;
|
||||
|
||||
if (minimum_baseline || natural_baseline)
|
||||
{
|
||||
baseline = pango_layout_get_baseline (layout) / PANGO_SCALE;
|
||||
if (minimum_baseline)
|
||||
*minimum_baseline = baseline;
|
||||
|
||||
if (natural_baseline)
|
||||
*natural_baseline = baseline;
|
||||
}
|
||||
|
||||
g_object_unref (layout);
|
||||
}
|
||||
|
||||
@@ -3578,7 +3598,9 @@ static void
|
||||
gtk_label_get_preferred_size (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
gint *minimum_size,
|
||||
gint *natural_size)
|
||||
gint *natural_size,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
GtkLabel *label = GTK_LABEL (widget);
|
||||
GtkLabelPrivate *priv = label->priv;
|
||||
@@ -3586,6 +3608,12 @@ gtk_label_get_preferred_size (GtkWidget *widget,
|
||||
PangoRectangle smallest_rect;
|
||||
GtkBorder border;
|
||||
|
||||
if (minimum_baseline)
|
||||
*minimum_baseline = -1;
|
||||
|
||||
if (natural_baseline)
|
||||
*natural_baseline = -1;
|
||||
|
||||
gtk_label_get_preferred_layout_size (label, &smallest_rect, &widest_rect);
|
||||
|
||||
/* Now that we have minimum and natural sizes in pango extents, apply a possible transform */
|
||||
@@ -3640,7 +3668,8 @@ gtk_label_get_preferred_size (GtkWidget *widget,
|
||||
get_size_for_allocation (label,
|
||||
GTK_ORIENTATION_VERTICAL,
|
||||
smallest_rect.height,
|
||||
minimum_size, natural_size);
|
||||
minimum_size, natural_size,
|
||||
NULL, NULL);
|
||||
|
||||
}
|
||||
else
|
||||
@@ -3667,7 +3696,16 @@ gtk_label_get_preferred_size (GtkWidget *widget,
|
||||
get_size_for_allocation (label,
|
||||
GTK_ORIENTATION_HORIZONTAL,
|
||||
widest_rect.width,
|
||||
minimum_size, natural_size);
|
||||
minimum_size, natural_size,
|
||||
minimum_baseline, natural_baseline);
|
||||
|
||||
if (priv->angle == 180)
|
||||
{
|
||||
if (minimum_baseline)
|
||||
*minimum_baseline = *minimum_size - *minimum_baseline;
|
||||
if (natural_baseline)
|
||||
*natural_baseline = *natural_size - *natural_baseline;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3680,6 +3718,12 @@ gtk_label_get_preferred_size (GtkWidget *widget,
|
||||
|
||||
*minimum_size += border.top + border.bottom;
|
||||
*natural_size += border.top + border.bottom;
|
||||
|
||||
if (minimum_baseline && *minimum_baseline != -1)
|
||||
*minimum_baseline += border.top;
|
||||
|
||||
if (natural_baseline && *natural_baseline != -1)
|
||||
*natural_baseline += border.top;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3688,7 +3732,7 @@ gtk_label_get_preferred_width (GtkWidget *widget,
|
||||
gint *minimum_size,
|
||||
gint *natural_size)
|
||||
{
|
||||
gtk_label_get_preferred_size (widget, GTK_ORIENTATION_HORIZONTAL, minimum_size, natural_size);
|
||||
gtk_label_get_preferred_size (widget, GTK_ORIENTATION_HORIZONTAL, minimum_size, natural_size, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -3696,7 +3740,7 @@ gtk_label_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum_size,
|
||||
gint *natural_size)
|
||||
{
|
||||
gtk_label_get_preferred_size (widget, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size);
|
||||
gtk_label_get_preferred_size (widget, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -3719,7 +3763,8 @@ gtk_label_get_preferred_width_for_height (GtkWidget *widget,
|
||||
|
||||
get_size_for_allocation (label, GTK_ORIENTATION_VERTICAL,
|
||||
MAX (1, height - border.top - border.bottom),
|
||||
minimum_width, natural_width);
|
||||
minimum_width, natural_width,
|
||||
NULL, NULL);
|
||||
|
||||
if (minimum_width)
|
||||
*minimum_width += border.right + border.left;
|
||||
@@ -3732,15 +3777,17 @@ gtk_label_get_preferred_width_for_height (GtkWidget *widget,
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_label_get_preferred_height_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum_height,
|
||||
gint *natural_height)
|
||||
gtk_label_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum_height,
|
||||
gint *natural_height,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
GtkLabel *label = GTK_LABEL (widget);
|
||||
GtkLabelPrivate *priv = label->priv;
|
||||
|
||||
if (priv->wrap && (priv->angle == 0 || priv->angle == 180 || priv->angle == 360))
|
||||
if (width != -1 && priv->wrap && (priv->angle == 0 || priv->angle == 180 || priv->angle == 360))
|
||||
{
|
||||
GtkBorder border;
|
||||
|
||||
@@ -3751,7 +3798,13 @@ gtk_label_get_preferred_height_for_width (GtkWidget *widget,
|
||||
|
||||
get_size_for_allocation (label, GTK_ORIENTATION_HORIZONTAL,
|
||||
MAX (1, width - border.left - border.right),
|
||||
minimum_height, natural_height);
|
||||
minimum_height, natural_height,
|
||||
minimum_baseline, natural_baseline);
|
||||
|
||||
if (minimum_baseline && *minimum_baseline != -1)
|
||||
*minimum_baseline += border.top;
|
||||
if (natural_baseline && *natural_baseline != -1)
|
||||
*natural_baseline += border.top;
|
||||
|
||||
if (minimum_height)
|
||||
*minimum_height += border.top + border.bottom;
|
||||
@@ -3760,7 +3813,18 @@ gtk_label_get_preferred_height_for_width (GtkWidget *widget,
|
||||
*natural_height += border.top + border.bottom;
|
||||
}
|
||||
else
|
||||
GTK_WIDGET_GET_CLASS (widget)->get_preferred_height (widget, minimum_height, natural_height);
|
||||
gtk_label_get_preferred_size (widget, GTK_ORIENTATION_VERTICAL, minimum_height, natural_height, minimum_baseline, natural_baseline);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_label_get_preferred_height_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum_height,
|
||||
gint *natural_height)
|
||||
{
|
||||
return gtk_label_get_preferred_height_and_baseline_for_width (widget, width,
|
||||
minimum_height, natural_height,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -3855,6 +3919,7 @@ get_layout_location (GtkLabel *label,
|
||||
gint req_height;
|
||||
gfloat xalign, yalign;
|
||||
PangoRectangle logical;
|
||||
gint baseline, layout_baseline, baseline_offset;
|
||||
|
||||
misc = GTK_MISC (label);
|
||||
widget = GTK_WIDGET (label);
|
||||
@@ -3887,6 +3952,15 @@ get_layout_location (GtkLabel *label,
|
||||
|
||||
x = floor (allocation.x + border.left + xalign * (allocation.width - req_width) - logical.x);
|
||||
|
||||
baseline_offset = 0;
|
||||
baseline = gtk_widget_get_allocated_baseline (widget);
|
||||
if (baseline != -1 && !priv->have_transform)
|
||||
{
|
||||
layout_baseline = pango_layout_get_baseline (priv->layout) / PANGO_SCALE;
|
||||
baseline_offset = baseline - layout_baseline;
|
||||
yalign = 0.0; /* Can't support yalign while baseline aligning */
|
||||
}
|
||||
|
||||
/* bgo#315462 - For single-line labels, *do* align the requisition with
|
||||
* respect to the allocation, even if we are under-allocated. For multi-line
|
||||
* labels, always show the top of the text when they are under-allocated. The
|
||||
@@ -3901,9 +3975,9 @@ get_layout_location (GtkLabel *label,
|
||||
* middle". You want to read the first line, at least, to get some context.
|
||||
*/
|
||||
if (pango_layout_get_line_count (priv->layout) == 1)
|
||||
y = floor (allocation.y + border.top + (allocation.height - req_height) * yalign) - logical.y;
|
||||
y = floor (allocation.y + border.top + (allocation.height - req_height) * yalign) - logical.y + baseline_offset;
|
||||
else
|
||||
y = floor (allocation.y + border.top + MAX ((allocation.height - req_height) * yalign, 0)) - logical.y;
|
||||
y = floor (allocation.y + border.top + MAX ((allocation.height - req_height) * yalign, 0)) - logical.y + baseline_offset;
|
||||
|
||||
if (xp)
|
||||
*xp = x;
|
||||
|
||||
@@ -2555,9 +2555,9 @@ list_store_text (GMarkupParseContext *context,
|
||||
* since the parser is not telling the builder about the domain.
|
||||
* However, it will work for gtk_builder_set_translation_domain() calls.
|
||||
*/
|
||||
translated = _gtk_builder_parser_translate (data->domain,
|
||||
info->context,
|
||||
string);
|
||||
translated = g_strdup (_gtk_builder_parser_translate (data->domain,
|
||||
info->context,
|
||||
string));
|
||||
g_free (string);
|
||||
string = translated;
|
||||
}
|
||||
|
||||
@@ -171,7 +171,9 @@ static const GDebugKey gtk_debug_keys[] = {
|
||||
{"printing", GTK_DEBUG_PRINTING},
|
||||
{"builder", GTK_DEBUG_BUILDER},
|
||||
{"size-request", GTK_DEBUG_SIZE_REQUEST},
|
||||
{"no-css-cache", GTK_DEBUG_NO_CSS_CACHE}
|
||||
{"no-css-cache", GTK_DEBUG_NO_CSS_CACHE},
|
||||
{"baselines", GTK_DEBUG_BASELINES},
|
||||
{"pixel-cache", GTK_DEBUG_PIXEL_CACHE}
|
||||
};
|
||||
#endif /* G_ENABLE_DEBUG */
|
||||
|
||||
@@ -1614,9 +1616,17 @@ gtk_main_do_event (GdkEvent *event)
|
||||
case GDK_EXPOSE:
|
||||
if (event->any.window && gtk_widget_get_double_buffered (event_widget))
|
||||
{
|
||||
gdk_window_begin_paint_region (event->any.window, event->expose.region);
|
||||
gtk_widget_send_expose (event_widget, event);
|
||||
gdk_window_end_paint (event->any.window);
|
||||
/* We handle exposes only on native windows, relying on the
|
||||
* draw() handler to propagate down to non-native windows.
|
||||
* This is ok now that we child windows always are considered
|
||||
* (semi)transparent.
|
||||
*/
|
||||
if (gdk_window_has_native (event->expose.window))
|
||||
{
|
||||
gdk_window_begin_paint_region (event->any.window, event->expose.region);
|
||||
gtk_widget_send_expose (event_widget, event);
|
||||
gdk_window_end_paint (event->any.window);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
#include "gtkintl.h"
|
||||
#include "gtkprivate.h"
|
||||
#include "gtktypebuiltins.h"
|
||||
#include "gtkwidgetprivate.h"
|
||||
|
||||
/* Properties */
|
||||
enum {
|
||||
@@ -308,25 +309,6 @@ gtk_menu_bar_get_property (GObject *object,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
get_preferred_size_for_size (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
gint size,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
{
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
if (size < 0)
|
||||
gtk_widget_get_preferred_width (widget, minimum, natural);
|
||||
else
|
||||
gtk_widget_get_preferred_width_for_height (widget, size, minimum, natural);
|
||||
else
|
||||
if (size < 0)
|
||||
gtk_widget_get_preferred_height (widget, minimum, natural);
|
||||
else
|
||||
gtk_widget_get_preferred_height_for_width (widget, size, minimum, natural);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_menu_bar_size_request (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
@@ -374,7 +356,7 @@ gtk_menu_bar_size_request (GtkWidget *widget,
|
||||
|
||||
if (gtk_widget_get_visible (child))
|
||||
{
|
||||
get_preferred_size_for_size (child, orientation, size, &child_minimum, &child_natural);
|
||||
_gtk_widget_get_preferred_size_for_size (child, orientation, size, &child_minimum, &child_natural, NULL, NULL);
|
||||
|
||||
if (use_toggle_size)
|
||||
{
|
||||
|
||||
@@ -1378,7 +1378,7 @@ gtk_menu_item_activate (GtkMenuItem *menu_item)
|
||||
/**
|
||||
* gtk_menu_item_toggle_size_request:
|
||||
* @menu_item: the menu item
|
||||
* @requisition: the requisition to use as signal data.
|
||||
* @requisition: (inout): the requisition to use as signal data.
|
||||
*
|
||||
* Emits the #GtkMenuItem::toggle-size-request signal on the given item.
|
||||
*/
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
#include "gtkactionhelper.h"
|
||||
#include "gtkwidgetprivate.h"
|
||||
#include "gtkaccellabel.h"
|
||||
#include "gtkimage.h"
|
||||
#include "gtkbox.h"
|
||||
|
||||
struct _GtkModelMenuItem
|
||||
{
|
||||
@@ -113,6 +115,51 @@ gtk_model_menu_item_setup (GtkModelMenuItem *item,
|
||||
GMenuModel *submenu;
|
||||
const gchar *key;
|
||||
GVariant *value;
|
||||
GtkWidget *label;
|
||||
|
||||
label = NULL;
|
||||
|
||||
/* In the case that we have an icon, make an HBox and put it beside
|
||||
* the label. Otherwise, we just have a label directly.
|
||||
*/
|
||||
if ((value = g_menu_model_get_item_attribute_value (model, item_index, "icon", NULL)))
|
||||
{
|
||||
GIcon *icon;
|
||||
|
||||
icon = g_icon_deserialize (value);
|
||||
|
||||
if (icon != NULL)
|
||||
{
|
||||
GtkWidget *image;
|
||||
GtkWidget *box;
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
|
||||
image = gtk_image_new_from_gicon (icon, GTK_ICON_SIZE_MENU);
|
||||
gtk_box_pack_start (GTK_BOX (box), image, FALSE, FALSE, 0);
|
||||
g_object_unref (icon);
|
||||
|
||||
label = gtk_accel_label_new ("");
|
||||
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
|
||||
gtk_accel_label_set_accel_widget (GTK_ACCEL_LABEL (label), GTK_WIDGET (item));
|
||||
gtk_box_pack_end (GTK_BOX (box), label, TRUE, TRUE, 0);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (item), box);
|
||||
|
||||
gtk_widget_show_all (box);
|
||||
}
|
||||
|
||||
g_variant_unref (value);
|
||||
}
|
||||
|
||||
if (label == NULL)
|
||||
{
|
||||
/* Ensure that the GtkAccelLabel has been created... */
|
||||
(void) gtk_menu_item_get_label (GTK_MENU_ITEM (item));
|
||||
label = gtk_bin_get_child (GTK_BIN (item));
|
||||
}
|
||||
|
||||
g_assert (label != NULL);
|
||||
|
||||
if ((submenu = g_menu_model_get_item_link (model, item_index, "submenu")))
|
||||
{
|
||||
@@ -141,7 +188,7 @@ gtk_model_menu_item_setup (GtkModelMenuItem *item,
|
||||
while (g_menu_attribute_iter_get_next (iter, &key, &value))
|
||||
{
|
||||
if (g_str_equal (key, "label") && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
|
||||
gtk_menu_item_set_label (GTK_MENU_ITEM (item), g_variant_get_string (value, NULL));
|
||||
gtk_label_set_text_with_mnemonic (GTK_LABEL (label), g_variant_get_string (value, NULL));
|
||||
|
||||
else if (g_str_equal (key, "accel") && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
|
||||
{
|
||||
@@ -151,16 +198,7 @@ gtk_model_menu_item_setup (GtkModelMenuItem *item,
|
||||
gtk_accelerator_parse (g_variant_get_string (value, NULL), &key, &modifiers);
|
||||
|
||||
if (key)
|
||||
{
|
||||
GtkAccelLabel *accel_label;
|
||||
|
||||
/* Ensure that the GtkAccelLabel has been created... */
|
||||
(void) gtk_menu_item_get_label (GTK_MENU_ITEM (item));
|
||||
accel_label = GTK_ACCEL_LABEL (gtk_bin_get_child (GTK_BIN (item)));
|
||||
g_assert (accel_label);
|
||||
|
||||
gtk_accel_label_set_accel (accel_label, key, modifiers);
|
||||
}
|
||||
gtk_accel_label_set_accel (GTK_ACCEL_LABEL (label), key, modifiers);
|
||||
}
|
||||
|
||||
else if (g_str_equal (key, "action") && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
|
||||
|
||||
@@ -2214,25 +2214,6 @@ gtk_notebook_get_preferred_tabs_size (GtkNotebook *notebook,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
get_preferred_size_for_size (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
gint size,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
{
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
if (size < 0)
|
||||
gtk_widget_get_preferred_width (widget, minimum, natural);
|
||||
else
|
||||
gtk_widget_get_preferred_width_for_height (widget, size, minimum, natural);
|
||||
else
|
||||
if (size < 0)
|
||||
gtk_widget_get_preferred_height (widget, minimum, natural);
|
||||
else
|
||||
gtk_widget_get_preferred_height_for_width (widget, size, minimum, natural);
|
||||
}
|
||||
|
||||
static void
|
||||
get_padding_and_border (GtkNotebook *notebook,
|
||||
GtkBorder *border)
|
||||
@@ -2282,11 +2263,13 @@ gtk_notebook_size_request (GtkWidget *widget,
|
||||
if (gtk_widget_get_visible (page->child))
|
||||
{
|
||||
vis_pages++;
|
||||
get_preferred_size_for_size (page->child,
|
||||
orientation,
|
||||
size,
|
||||
&child_minimum,
|
||||
&child_natural);
|
||||
_gtk_widget_get_preferred_size_for_size (page->child,
|
||||
orientation,
|
||||
size,
|
||||
&child_minimum,
|
||||
&child_natural,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
*minimum = MAX (*minimum, child_minimum);
|
||||
*natural = MAX (*natural, child_natural);
|
||||
@@ -8195,9 +8178,11 @@ gtk_notebook_set_tab_reorderable (GtkNotebook *notebook,
|
||||
if (!list)
|
||||
return;
|
||||
|
||||
reorderable = reorderable != FALSE;
|
||||
|
||||
if (GTK_NOTEBOOK_PAGE (list)->reorderable != reorderable)
|
||||
{
|
||||
GTK_NOTEBOOK_PAGE (list)->reorderable = (reorderable == TRUE);
|
||||
GTK_NOTEBOOK_PAGE (list)->reorderable = reorderable;
|
||||
gtk_widget_child_notify (child, "reorderable");
|
||||
}
|
||||
}
|
||||
@@ -8288,9 +8273,11 @@ gtk_notebook_set_tab_detachable (GtkNotebook *notebook,
|
||||
if (!list)
|
||||
return;
|
||||
|
||||
detachable = detachable != FALSE;
|
||||
|
||||
if (GTK_NOTEBOOK_PAGE (list)->detachable != detachable)
|
||||
{
|
||||
GTK_NOTEBOOK_PAGE (list)->detachable = (detachable == TRUE);
|
||||
GTK_NOTEBOOK_PAGE (list)->detachable = detachable;
|
||||
gtk_widget_child_notify (child, "detachable");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -399,6 +399,10 @@ gtk_overlay_get_child_position (GtkOverlay *overlay,
|
||||
case GTK_ALIGN_END:
|
||||
alloc->x += main_alloc.width - req.width;
|
||||
break;
|
||||
case GTK_ALIGN_BASELINE:
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
|
||||
alloc->y = main_alloc.y;
|
||||
@@ -418,6 +422,10 @@ gtk_overlay_get_child_position (GtkOverlay *overlay,
|
||||
case GTK_ALIGN_END:
|
||||
alloc->y += main_alloc.height - req.height;
|
||||
break;
|
||||
case GTK_ALIGN_BASELINE:
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "gtkorientableprivate.h"
|
||||
#include "gtkprivate.h"
|
||||
#include "gtkintl.h"
|
||||
#include "gtkwidgetprivate.h"
|
||||
#include "a11y/gtkpanedaccessible.h"
|
||||
|
||||
/**
|
||||
@@ -870,22 +871,166 @@ gtk_paned_finalize (GObject *object)
|
||||
}
|
||||
|
||||
static void
|
||||
get_preferred_size_for_size (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
gint size,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
gtk_paned_compute_position (GtkPaned *paned,
|
||||
gint allocation,
|
||||
gint child1_req,
|
||||
gint child2_req,
|
||||
gint *min_pos,
|
||||
gint *max_pos,
|
||||
gint *out_pos)
|
||||
{
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
if (size < 0)
|
||||
gtk_widget_get_preferred_width (widget, minimum, natural);
|
||||
else
|
||||
gtk_widget_get_preferred_width_for_height (widget, size, minimum, natural);
|
||||
GtkPanedPrivate *priv = paned->priv;
|
||||
gint min, max, pos;
|
||||
|
||||
min = priv->child1_shrink ? 0 : child1_req;
|
||||
|
||||
max = allocation;
|
||||
if (!priv->child2_shrink)
|
||||
max = MAX (1, max - child2_req);
|
||||
max = MAX (min, max);
|
||||
|
||||
if (!priv->position_set)
|
||||
{
|
||||
if (priv->child1_resize && !priv->child2_resize)
|
||||
pos = MAX (0, allocation - child2_req);
|
||||
else if (!priv->child1_resize && priv->child2_resize)
|
||||
pos = child1_req;
|
||||
else if (child1_req + child2_req != 0)
|
||||
pos = allocation * ((gdouble)child1_req / (child1_req + child2_req)) + 0.5;
|
||||
else
|
||||
pos = allocation * 0.5 + 0.5;
|
||||
}
|
||||
else
|
||||
if (size < 0)
|
||||
gtk_widget_get_preferred_height (widget, minimum, natural);
|
||||
else
|
||||
gtk_widget_get_preferred_height_for_width (widget, size, minimum, natural);
|
||||
{
|
||||
/* If the position was set before the initial allocation.
|
||||
* (priv->last_allocation <= 0) just clamp it and leave it.
|
||||
*/
|
||||
if (priv->last_allocation > 0)
|
||||
{
|
||||
if (priv->child1_resize && !priv->child2_resize)
|
||||
pos = priv->child1_size + allocation - priv->last_allocation;
|
||||
else if (!(!priv->child1_resize && priv->child2_resize))
|
||||
pos = allocation * ((gdouble) priv->child1_size / (priv->last_allocation)) + 0.5;
|
||||
else
|
||||
pos = priv->child1_size;
|
||||
}
|
||||
else
|
||||
pos = priv->child1_size;
|
||||
}
|
||||
|
||||
pos = CLAMP (pos, min, max);
|
||||
|
||||
if (min_pos)
|
||||
*min_pos = min;
|
||||
if (max_pos)
|
||||
*max_pos = max;
|
||||
if (out_pos)
|
||||
*out_pos = pos;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_paned_get_preferred_size_for_orientation (GtkWidget *widget,
|
||||
gint size,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
{
|
||||
GtkPaned *paned = GTK_PANED (widget);
|
||||
GtkPanedPrivate *priv = paned->priv;
|
||||
gint child_min, child_nat;
|
||||
|
||||
*minimum = *natural = 0;
|
||||
|
||||
if (priv->child1 && gtk_widget_get_visible (priv->child1))
|
||||
{
|
||||
_gtk_widget_get_preferred_size_for_size (priv->child1, priv->orientation, size, &child_min, &child_nat, NULL, NULL);
|
||||
if (priv->child1_shrink)
|
||||
*minimum = 0;
|
||||
else
|
||||
*minimum = child_min;
|
||||
*natural = child_nat;
|
||||
}
|
||||
|
||||
if (priv->child2 && gtk_widget_get_visible (priv->child2))
|
||||
{
|
||||
_gtk_widget_get_preferred_size_for_size (priv->child2, priv->orientation, size, &child_min, &child_nat, NULL, NULL);
|
||||
|
||||
if (!priv->child2_shrink)
|
||||
*minimum += child_min;
|
||||
*natural += child_nat;
|
||||
}
|
||||
|
||||
if (priv->child1 && gtk_widget_get_visible (priv->child1) &&
|
||||
priv->child2 && gtk_widget_get_visible (priv->child2))
|
||||
{
|
||||
gint handle_size;
|
||||
|
||||
gtk_widget_style_get (widget, "handle-size", &handle_size, NULL);
|
||||
|
||||
*minimum += handle_size;
|
||||
*natural += handle_size;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_paned_get_preferred_size_for_opposite_orientation (GtkWidget *widget,
|
||||
gint size,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
{
|
||||
GtkPaned *paned = GTK_PANED (widget);
|
||||
GtkPanedPrivate *priv = paned->priv;
|
||||
gint for_child1, for_child2;
|
||||
gint child_min, child_nat;
|
||||
|
||||
if (size > -1 &&
|
||||
priv->child1 && gtk_widget_get_visible (priv->child1) &&
|
||||
priv->child2 && gtk_widget_get_visible (priv->child2))
|
||||
{
|
||||
gint child1_req, child2_req;
|
||||
gint handle_size;
|
||||
|
||||
gtk_widget_style_get (widget, "handle-size", &handle_size, NULL);
|
||||
|
||||
_gtk_widget_get_preferred_size_for_size (priv->child1, priv->orientation, -1, &child1_req, NULL, NULL, NULL);
|
||||
_gtk_widget_get_preferred_size_for_size (priv->child2, priv->orientation, -1, &child2_req, NULL, NULL, NULL);
|
||||
|
||||
gtk_paned_compute_position (paned,
|
||||
size, child1_req, child2_req,
|
||||
NULL, NULL, &for_child1);
|
||||
|
||||
for_child2 = size - for_child1 - handle_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
for_child1 = size;
|
||||
for_child2 = size;
|
||||
}
|
||||
|
||||
*minimum = *natural = 0;
|
||||
|
||||
if (priv->child1 && gtk_widget_get_visible (priv->child1))
|
||||
{
|
||||
_gtk_widget_get_preferred_size_for_size (priv->child1,
|
||||
OPPOSITE_ORIENTATION (priv->orientation),
|
||||
for_child1,
|
||||
&child_min, &child_nat,
|
||||
NULL, NULL);
|
||||
|
||||
*minimum = child_min;
|
||||
*natural = child_nat;
|
||||
}
|
||||
|
||||
if (priv->child2 && gtk_widget_get_visible (priv->child2))
|
||||
{
|
||||
_gtk_widget_get_preferred_size_for_size (priv->child2,
|
||||
OPPOSITE_ORIENTATION (priv->orientation),
|
||||
for_child2,
|
||||
&child_min, &child_nat,
|
||||
NULL, NULL);
|
||||
|
||||
*minimum = MAX (*minimum, child_min);
|
||||
*natural = MAX (*natural, child_nat);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -897,50 +1042,11 @@ gtk_paned_get_preferred_size (GtkWidget *widget,
|
||||
{
|
||||
GtkPaned *paned = GTK_PANED (widget);
|
||||
GtkPanedPrivate *priv = paned->priv;
|
||||
gint child_min, child_nat;
|
||||
|
||||
*minimum = *natural = 0;
|
||||
|
||||
if (priv->child1 && gtk_widget_get_visible (priv->child1))
|
||||
{
|
||||
get_preferred_size_for_size (priv->child1, orientation, size, &child_min, &child_nat);
|
||||
if (priv->child1_shrink && priv->orientation == orientation)
|
||||
*minimum = 0;
|
||||
else
|
||||
*minimum = child_min;
|
||||
*natural = child_nat;
|
||||
}
|
||||
|
||||
if (priv->child2 && gtk_widget_get_visible (priv->child2))
|
||||
{
|
||||
get_preferred_size_for_size (priv->child2, orientation, size, &child_min, &child_nat);
|
||||
|
||||
if (priv->orientation == orientation)
|
||||
{
|
||||
if (!priv->child2_shrink)
|
||||
*minimum += child_min;
|
||||
*natural += child_nat;
|
||||
}
|
||||
else
|
||||
{
|
||||
*minimum = MAX (*minimum, child_min);
|
||||
*natural = MAX (*natural, child_nat);
|
||||
}
|
||||
}
|
||||
|
||||
if (priv->child1 && gtk_widget_get_visible (priv->child1) &&
|
||||
priv->child2 && gtk_widget_get_visible (priv->child2))
|
||||
{
|
||||
gint handle_size;
|
||||
|
||||
gtk_widget_style_get (widget, "handle-size", &handle_size, NULL);
|
||||
|
||||
if (priv->orientation == orientation)
|
||||
{
|
||||
*minimum += handle_size;
|
||||
*natural += handle_size;
|
||||
}
|
||||
}
|
||||
if (orientation == priv->orientation)
|
||||
return gtk_paned_get_preferred_size_for_orientation (widget, size, minimum, natural);
|
||||
else
|
||||
return gtk_paned_get_preferred_size_for_opposite_orientation (widget, size, minimum, natural);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2082,41 +2188,10 @@ gtk_paned_calc_position (GtkPaned *paned,
|
||||
old_min_position = priv->min_position;
|
||||
old_max_position = priv->max_position;
|
||||
|
||||
priv->min_position = priv->child1_shrink ? 0 : child1_req;
|
||||
|
||||
priv->max_position = allocation;
|
||||
if (!priv->child2_shrink)
|
||||
priv->max_position = MAX (1, priv->max_position - child2_req);
|
||||
priv->max_position = MAX (priv->min_position, priv->max_position);
|
||||
|
||||
if (!priv->position_set)
|
||||
{
|
||||
if (priv->child1_resize && !priv->child2_resize)
|
||||
priv->child1_size = MAX (0, allocation - child2_req);
|
||||
else if (!priv->child1_resize && priv->child2_resize)
|
||||
priv->child1_size = child1_req;
|
||||
else if (child1_req + child2_req != 0)
|
||||
priv->child1_size = allocation * ((gdouble)child1_req / (child1_req + child2_req)) + 0.5;
|
||||
else
|
||||
priv->child1_size = allocation * 0.5 + 0.5;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If the position was set before the initial allocation.
|
||||
* (priv->last_allocation <= 0) just clamp it and leave it.
|
||||
*/
|
||||
if (priv->last_allocation > 0)
|
||||
{
|
||||
if (priv->child1_resize && !priv->child2_resize)
|
||||
priv->child1_size += allocation - priv->last_allocation;
|
||||
else if (!(!priv->child1_resize && priv->child2_resize))
|
||||
priv->child1_size = allocation * ((gdouble) priv->child1_size / (priv->last_allocation)) + 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
priv->child1_size = CLAMP (priv->child1_size,
|
||||
priv->min_position,
|
||||
priv->max_position);
|
||||
gtk_paned_compute_position (paned,
|
||||
allocation, child1_req, child2_req,
|
||||
&priv->min_position, &priv->max_position,
|
||||
&priv->child1_size);
|
||||
|
||||
if (priv->child1)
|
||||
gtk_paned_set_child_visible (paned, 0, priv->child1_size != 0);
|
||||
|
||||
@@ -0,0 +1,395 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 2013 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gtkdebug.h"
|
||||
#include "gtkpixelcacheprivate.h"
|
||||
|
||||
#define BLOW_CACHE_TIMEOUT_SEC 20
|
||||
|
||||
/* The extra size of the offscreen surface we allocate
|
||||
to make scrolling more efficient */
|
||||
#define EXTRA_SIZE 64
|
||||
|
||||
/* When resizing viewport to smaller we allow this extra
|
||||
size to avoid constantly reallocating when resizing */
|
||||
#define ALLOW_LARGER_SIZE 32
|
||||
|
||||
struct _GtkPixelCache {
|
||||
cairo_surface_t *surface;
|
||||
|
||||
/* Valid if surface != NULL */
|
||||
int surface_x;
|
||||
int surface_y;
|
||||
int surface_w;
|
||||
int surface_h;
|
||||
|
||||
/* may be null if not dirty */
|
||||
cairo_region_t *surface_dirty;
|
||||
|
||||
guint timeout_tag;
|
||||
};
|
||||
|
||||
GtkPixelCache *
|
||||
_gtk_pixel_cache_new ()
|
||||
{
|
||||
GtkPixelCache *cache;
|
||||
|
||||
cache = g_new0 (GtkPixelCache, 1);
|
||||
|
||||
return cache;
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_pixel_cache_free (GtkPixelCache *cache)
|
||||
{
|
||||
if (cache == NULL)
|
||||
return;
|
||||
|
||||
if (cache->timeout_tag)
|
||||
g_source_remove (cache->timeout_tag);
|
||||
|
||||
if (cache->surface != NULL)
|
||||
cairo_surface_destroy (cache->surface);
|
||||
|
||||
if (cache->surface_dirty != NULL)
|
||||
cairo_region_destroy (cache->surface_dirty);
|
||||
|
||||
g_free (cache);
|
||||
}
|
||||
|
||||
/* Region is in canvas coordinates */
|
||||
void
|
||||
_gtk_pixel_cache_invalidate (GtkPixelCache *cache,
|
||||
cairo_region_t *region)
|
||||
{
|
||||
cairo_rectangle_int_t r;
|
||||
cairo_region_t *free_region = NULL;
|
||||
|
||||
if (cache->surface == NULL ||
|
||||
(region != NULL && cairo_region_is_empty (region)))
|
||||
return;
|
||||
|
||||
if (region == NULL)
|
||||
{
|
||||
r.x = cache->surface_x;
|
||||
r.y = cache->surface_y;
|
||||
r.width = cache->surface_w;
|
||||
r.height = cache->surface_h;
|
||||
|
||||
free_region = region =
|
||||
cairo_region_create_rectangle (&r);
|
||||
}
|
||||
|
||||
if (cache->surface_dirty == NULL)
|
||||
{
|
||||
cache->surface_dirty = cairo_region_copy (region);
|
||||
cairo_region_translate (cache->surface_dirty,
|
||||
-cache->surface_x,
|
||||
-cache->surface_y);
|
||||
}
|
||||
else
|
||||
{
|
||||
cairo_region_translate (region,
|
||||
-cache->surface_x,
|
||||
-cache->surface_y);
|
||||
cairo_region_union (cache->surface_dirty, region);
|
||||
cairo_region_translate (region,
|
||||
cache->surface_x,
|
||||
cache->surface_y);
|
||||
}
|
||||
|
||||
if (free_region)
|
||||
cairo_region_destroy (free_region);
|
||||
|
||||
r.x = 0;
|
||||
r.y = 0;
|
||||
r.width = cache->surface_w;
|
||||
r.height = cache->surface_h;
|
||||
|
||||
cairo_region_intersect_rectangle (cache->surface_dirty, &r);
|
||||
}
|
||||
|
||||
static void
|
||||
_gtk_pixel_cache_create_surface_if_needed (GtkPixelCache *cache,
|
||||
GdkWindow *window,
|
||||
cairo_rectangle_int_t *view_rect,
|
||||
cairo_rectangle_int_t *canvas_rect)
|
||||
{
|
||||
cairo_rectangle_int_t rect;
|
||||
int surface_w, surface_h;
|
||||
cairo_content_t content;
|
||||
cairo_pattern_t *bg;
|
||||
double red, green, blue, alpha;
|
||||
|
||||
content = CAIRO_CONTENT_COLOR_ALPHA;
|
||||
bg = gdk_window_get_background_pattern (window);
|
||||
if (bg != NULL &&
|
||||
cairo_pattern_get_type (bg) == CAIRO_PATTERN_TYPE_SOLID &&
|
||||
cairo_pattern_get_rgba (bg, &red, &green, &blue, &alpha) == CAIRO_STATUS_SUCCESS &&
|
||||
alpha == 1.0)
|
||||
content = CAIRO_CONTENT_COLOR;
|
||||
|
||||
surface_w = view_rect->width;
|
||||
if (canvas_rect->width > surface_w)
|
||||
surface_w = MIN (surface_w + EXTRA_SIZE, canvas_rect->width);
|
||||
|
||||
surface_h = view_rect->height;
|
||||
if (canvas_rect->height > surface_h)
|
||||
surface_h = MIN (surface_h + EXTRA_SIZE, canvas_rect->height);
|
||||
|
||||
/* If current surface can't fit view_rect or is too large, kill it */
|
||||
if (cache->surface != NULL &&
|
||||
(cairo_surface_get_content (cache->surface) != content ||
|
||||
cache->surface_w < view_rect->width ||
|
||||
cache->surface_w > surface_w + ALLOW_LARGER_SIZE ||
|
||||
cache->surface_h < view_rect->height ||
|
||||
cache->surface_h > surface_h + ALLOW_LARGER_SIZE))
|
||||
{
|
||||
cairo_surface_destroy (cache->surface);
|
||||
cache->surface = NULL;
|
||||
if (cache->surface_dirty)
|
||||
cairo_region_destroy (cache->surface_dirty);
|
||||
cache->surface_dirty = NULL;
|
||||
}
|
||||
|
||||
/* Don't allocate a surface if view >= canvas, as we won't
|
||||
be scrolling then anyway */
|
||||
if (cache->surface == NULL &&
|
||||
(view_rect->width < canvas_rect->width ||
|
||||
view_rect->height < canvas_rect->height))
|
||||
{
|
||||
cache->surface_x = -canvas_rect->x;
|
||||
cache->surface_y = -canvas_rect->y;
|
||||
cache->surface_w = surface_w;
|
||||
cache->surface_h = surface_h;
|
||||
|
||||
cache->surface =
|
||||
gdk_window_create_similar_surface (window, content,
|
||||
surface_w, surface_h);
|
||||
rect.x = 0;
|
||||
rect.y = 0;
|
||||
rect.width = surface_w;
|
||||
rect.height = surface_h;
|
||||
cache->surface_dirty =
|
||||
cairo_region_create_rectangle (&rect);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_pixel_cache_set_position (GtkPixelCache *cache,
|
||||
cairo_rectangle_int_t *view_rect,
|
||||
cairo_rectangle_int_t *canvas_rect)
|
||||
{
|
||||
cairo_rectangle_int_t r, view_pos;
|
||||
cairo_region_t *copy_region;
|
||||
int new_surf_x, new_surf_y;
|
||||
cairo_t *backing_cr;
|
||||
|
||||
if (cache->surface == NULL)
|
||||
return;
|
||||
|
||||
/* Position of view inside canvas */
|
||||
view_pos.x = -canvas_rect->x;
|
||||
view_pos.y = -canvas_rect->y;
|
||||
view_pos.width = view_rect->width;
|
||||
view_pos.height = view_rect->height;
|
||||
|
||||
/* Reposition so all is visible */
|
||||
if (view_pos.x < cache->surface_x ||
|
||||
view_pos.x + view_pos.width >
|
||||
cache->surface_x + cache->surface_w ||
|
||||
view_pos.y < cache->surface_y ||
|
||||
view_pos.y + view_pos.height >
|
||||
cache->surface_y + cache->surface_h)
|
||||
{
|
||||
new_surf_x = cache->surface_x;
|
||||
if (view_pos.x < cache->surface_x)
|
||||
new_surf_x = MAX (view_pos.x + view_pos.width - cache->surface_w, 0);
|
||||
else if (view_pos.x + view_pos.width >
|
||||
cache->surface_x + cache->surface_w)
|
||||
new_surf_x = MIN (view_pos.x, canvas_rect->width - cache->surface_w);
|
||||
|
||||
new_surf_y = cache->surface_y;
|
||||
if (view_pos.y < cache->surface_y)
|
||||
new_surf_y = MAX (view_pos.y + view_pos.height - cache->surface_h, 0);
|
||||
else if (view_pos.y + view_pos.height >
|
||||
cache->surface_y + cache->surface_h)
|
||||
new_surf_y = MIN (view_pos.y, canvas_rect->height - cache->surface_h);
|
||||
|
||||
r.x = 0;
|
||||
r.y = 0;
|
||||
r.width = cache->surface_w;
|
||||
r.height = cache->surface_h;
|
||||
copy_region = cairo_region_create_rectangle (&r);
|
||||
|
||||
if (cache->surface_dirty)
|
||||
{
|
||||
cairo_region_subtract (copy_region, cache->surface_dirty);
|
||||
cairo_region_destroy (cache->surface_dirty);
|
||||
cache->surface_dirty = NULL;
|
||||
}
|
||||
|
||||
cairo_region_translate (copy_region,
|
||||
cache->surface_x - new_surf_x,
|
||||
cache->surface_y - new_surf_y);
|
||||
cairo_region_intersect_rectangle (copy_region, &r);
|
||||
|
||||
backing_cr = cairo_create (cache->surface);
|
||||
gdk_cairo_region (backing_cr, copy_region);
|
||||
cairo_set_operator (backing_cr, CAIRO_OPERATOR_SOURCE);
|
||||
cairo_clip (backing_cr);
|
||||
cairo_push_group (backing_cr);
|
||||
cairo_set_source_surface (backing_cr, cache->surface,
|
||||
cache->surface_x - new_surf_x,
|
||||
cache->surface_y - new_surf_y);
|
||||
cairo_paint (backing_cr);
|
||||
cairo_pop_group_to_source (backing_cr);
|
||||
cairo_paint (backing_cr);
|
||||
cairo_destroy (backing_cr);
|
||||
|
||||
cache->surface_x = new_surf_x;
|
||||
cache->surface_y = new_surf_y;
|
||||
|
||||
cairo_region_xor_rectangle (copy_region, &r);
|
||||
cache->surface_dirty = copy_region;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_pixel_cache_repaint (GtkPixelCache *cache,
|
||||
GtkPixelCacheDrawFunc draw,
|
||||
cairo_rectangle_int_t *view_rect,
|
||||
cairo_rectangle_int_t *canvas_rect,
|
||||
gpointer user_data)
|
||||
{
|
||||
cairo_t *backing_cr;
|
||||
|
||||
if (cache->surface &&
|
||||
cache->surface_dirty &&
|
||||
!cairo_region_is_empty (cache->surface_dirty))
|
||||
{
|
||||
backing_cr = cairo_create (cache->surface);
|
||||
gdk_cairo_region (backing_cr, cache->surface_dirty);
|
||||
cairo_clip (backing_cr);
|
||||
cairo_translate (backing_cr,
|
||||
-cache->surface_x - canvas_rect->x - view_rect->x,
|
||||
-cache->surface_y - canvas_rect->y - view_rect->y);
|
||||
cairo_set_source_rgba (backing_cr,
|
||||
0.0, 0, 0, 0.0);
|
||||
cairo_set_operator (backing_cr, CAIRO_OPERATOR_SOURCE);
|
||||
cairo_paint (backing_cr);
|
||||
|
||||
cairo_set_operator (backing_cr, CAIRO_OPERATOR_OVER);
|
||||
|
||||
cairo_save (backing_cr);
|
||||
draw (backing_cr, user_data);
|
||||
cairo_restore (backing_cr);
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (gtk_get_debug_flags () & GTK_DEBUG_PIXEL_CACHE)
|
||||
{
|
||||
GdkRGBA colors[] = {
|
||||
{ 1, 0, 0, 0.08},
|
||||
{ 0, 1, 0, 0.08},
|
||||
{ 0, 0, 1, 0.08},
|
||||
{ 1, 0, 1, 0.08},
|
||||
{ 1, 1, 0, 0.08},
|
||||
{ 0, 1, 1, 0.08},
|
||||
};
|
||||
static int current_color = 0;
|
||||
|
||||
gdk_cairo_set_source_rgba (backing_cr, &colors[(current_color++) % G_N_ELEMENTS (colors)]);
|
||||
cairo_paint (backing_cr);
|
||||
}
|
||||
#endif
|
||||
|
||||
cairo_destroy (backing_cr);
|
||||
}
|
||||
|
||||
if (cache->surface_dirty)
|
||||
{
|
||||
cairo_region_destroy (cache->surface_dirty);
|
||||
cache->surface_dirty = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
blow_cache_cb (gpointer user_data)
|
||||
{
|
||||
GtkPixelCache *cache = user_data;
|
||||
|
||||
cache->timeout_tag = 0;
|
||||
|
||||
if (cache->surface)
|
||||
{
|
||||
cairo_surface_destroy (cache->surface);
|
||||
cache->surface = NULL;
|
||||
if (cache->surface_dirty)
|
||||
cairo_region_destroy (cache->surface_dirty);
|
||||
cache->surface_dirty = NULL;
|
||||
}
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_gtk_pixel_cache_draw (GtkPixelCache *cache,
|
||||
cairo_t *cr,
|
||||
GdkWindow *window,
|
||||
/* View position in widget coords */
|
||||
cairo_rectangle_int_t *view_rect,
|
||||
/* Size and position of canvas in view coords */
|
||||
cairo_rectangle_int_t *canvas_rect,
|
||||
GtkPixelCacheDrawFunc draw,
|
||||
gpointer user_data)
|
||||
{
|
||||
if (cache->timeout_tag)
|
||||
g_source_remove (cache->timeout_tag);
|
||||
|
||||
cache->timeout_tag = g_timeout_add_seconds (BLOW_CACHE_TIMEOUT_SEC,
|
||||
blow_cache_cb, cache);
|
||||
|
||||
_gtk_pixel_cache_create_surface_if_needed (cache, window,
|
||||
view_rect, canvas_rect);
|
||||
_gtk_pixel_cache_set_position (cache, view_rect, canvas_rect);
|
||||
_gtk_pixel_cache_repaint (cache, draw, view_rect, canvas_rect, user_data);
|
||||
|
||||
if (cache->surface &&
|
||||
/* Don't use backing surface if rendering elsewhere */
|
||||
cairo_surface_get_type (cache->surface) == cairo_surface_get_type (cairo_get_target (cr)))
|
||||
{
|
||||
cairo_save (cr);
|
||||
cairo_set_source_surface (cr, cache->surface,
|
||||
cache->surface_x + view_rect->x + canvas_rect->x,
|
||||
cache->surface_y + view_rect->y + canvas_rect->y);
|
||||
cairo_rectangle (cr, view_rect->x, view_rect->y,
|
||||
view_rect->width, view_rect->height);
|
||||
cairo_fill (cr);
|
||||
cairo_restore (cr);
|
||||
}
|
||||
else
|
||||
{
|
||||
cairo_rectangle (cr,
|
||||
view_rect->x, view_rect->y,
|
||||
view_rect->width, view_rect->height);
|
||||
cairo_clip (cr);
|
||||
draw (cr, user_data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright © 2013 Red Hat Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Alexander Larsson <alexl@gnome.org>
|
||||
*/
|
||||
|
||||
#ifndef __GTK_PIXEL_CACHE_PRIVATE_H__
|
||||
#define __GTK_PIXEL_CACHE_PRIVATE_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <gtkwidget.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GtkPixelCache GtkPixelCache;
|
||||
|
||||
typedef void (*GtkPixelCacheDrawFunc) (cairo_t *cr,
|
||||
gpointer user_data);
|
||||
|
||||
GtkPixelCache *_gtk_pixel_cache_new (void);
|
||||
void _gtk_pixel_cache_free (GtkPixelCache *cache);
|
||||
void _gtk_pixel_cache_invalidate (GtkPixelCache *cache,
|
||||
cairo_region_t *region);
|
||||
void _gtk_pixel_cache_draw (GtkPixelCache *cache,
|
||||
cairo_t *cr,
|
||||
GdkWindow *window,
|
||||
cairo_rectangle_int_t *view_rect,
|
||||
cairo_rectangle_int_t *canvas_rect,
|
||||
GtkPixelCacheDrawFunc draw,
|
||||
gpointer user_data);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_PIXEL_CACHE_PRIVATE_H__ */
|
||||
@@ -170,6 +170,7 @@ struct _GtkPlacesSidebar {
|
||||
char *drop_target_uri;
|
||||
|
||||
guint show_desktop : 1;
|
||||
guint show_connect_to_server : 1;
|
||||
};
|
||||
|
||||
struct _GtkPlacesSidebarClass {
|
||||
@@ -180,10 +181,12 @@ struct _GtkPlacesSidebarClass {
|
||||
GtkPlacesOpenFlags open_flags);
|
||||
void (* populate_popup) (GtkPlacesSidebar *sidebar,
|
||||
GtkMenu *menu,
|
||||
GFile *selected_item);
|
||||
GFile *selected_item,
|
||||
GVolume *selected_volume);
|
||||
void (* show_error_message) (GtkPlacesSidebar *sidebar,
|
||||
const char *primary,
|
||||
const char *secondary);
|
||||
void (* show_connect_to_server) (GtkPlacesSidebar *sidebar);
|
||||
GdkDragAction (* drag_action_requested) (GtkPlacesSidebar *sidebar,
|
||||
GdkDragContext *context,
|
||||
GFile *dest_file,
|
||||
@@ -221,6 +224,7 @@ typedef enum {
|
||||
PLACES_MOUNTED_VOLUME,
|
||||
PLACES_BOOKMARK,
|
||||
PLACES_HEADING,
|
||||
PLACES_CONNECT_TO_SERVER,
|
||||
PLACES_DROP_FEEDBACK
|
||||
} PlaceType;
|
||||
|
||||
@@ -235,6 +239,7 @@ enum {
|
||||
OPEN_LOCATION,
|
||||
POPULATE_POPUP,
|
||||
SHOW_ERROR_MESSAGE,
|
||||
SHOW_CONNECT_TO_SERVER,
|
||||
DRAG_ACTION_REQUESTED,
|
||||
DRAG_ACTION_ASK,
|
||||
DRAG_PERFORM_DROP,
|
||||
@@ -245,15 +250,17 @@ enum {
|
||||
PROP_LOCATION = 1,
|
||||
PROP_OPEN_FLAGS,
|
||||
PROP_SHOW_DESKTOP,
|
||||
PROP_SHOW_CONNECT_TO_SERVER,
|
||||
NUM_PROPERTIES,
|
||||
};
|
||||
|
||||
/* Names for themed icons */
|
||||
#define ICON_NAME_HOME "user-home-symbolic"
|
||||
#define ICON_NAME_DESKTOP "user-desktop"
|
||||
#define ICON_NAME_FILESYSTEM "drive-harddisk-symbolic"
|
||||
#define ICON_NAME_EJECT "media-eject-symbolic"
|
||||
#define ICON_NAME_NETWORK "network-workgroup-symbolic"
|
||||
#define ICON_NAME_HOME "user-home-symbolic"
|
||||
#define ICON_NAME_DESKTOP "user-desktop"
|
||||
#define ICON_NAME_FILESYSTEM "drive-harddisk-symbolic"
|
||||
#define ICON_NAME_EJECT "media-eject-symbolic"
|
||||
#define ICON_NAME_NETWORK "network-workgroup-symbolic"
|
||||
#define ICON_NAME_NETWORK_SERVER "network-server-symbolic"
|
||||
|
||||
#define ICON_NAME_FOLDER_DESKTOP "user-desktop"
|
||||
#define ICON_NAME_FOLDER_DOCUMENTS "folder-documents-symbolic"
|
||||
@@ -336,10 +343,10 @@ emit_open_location (GtkPlacesSidebar *sidebar, GFile *location, GtkPlacesOpenFla
|
||||
}
|
||||
|
||||
static void
|
||||
emit_populate_popup (GtkPlacesSidebar *sidebar, GtkMenu *menu, GFile *selected_item)
|
||||
emit_populate_popup (GtkPlacesSidebar *sidebar, GtkMenu *menu, GFile *selected_item, GVolume *selected_volume)
|
||||
{
|
||||
g_signal_emit (sidebar, places_sidebar_signals[POPULATE_POPUP], 0,
|
||||
menu, selected_item);
|
||||
menu, selected_item, selected_volume);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -349,6 +356,12 @@ emit_show_error_message (GtkPlacesSidebar *sidebar, const char *primary, const c
|
||||
primary, secondary);
|
||||
}
|
||||
|
||||
static void
|
||||
emit_show_connect_to_server (GtkPlacesSidebar *sidebar)
|
||||
{
|
||||
g_signal_emit (sidebar, places_sidebar_signals[SHOW_CONNECT_TO_SERVER], 0);
|
||||
}
|
||||
|
||||
static GdkDragAction
|
||||
emit_drag_action_requested (GtkPlacesSidebar *sidebar,
|
||||
GdkDragContext *context,
|
||||
@@ -1062,6 +1075,16 @@ update_places (GtkPlacesSidebar *sidebar)
|
||||
_("Browse the contents of the network"));
|
||||
g_object_unref (icon);
|
||||
|
||||
if (sidebar->show_connect_to_server) {
|
||||
icon = g_themed_icon_new (ICON_NAME_NETWORK_SERVER);
|
||||
add_place (sidebar, PLACES_CONNECT_TO_SERVER,
|
||||
SECTION_NETWORK,
|
||||
_("Connect to Server"), icon, NULL,
|
||||
NULL, NULL, NULL, 0,
|
||||
_("Connect to a network server address"));
|
||||
g_object_unref (icon);
|
||||
}
|
||||
|
||||
network_volumes = g_list_reverse (network_volumes);
|
||||
for (l = network_volumes; l != NULL; l = l->next) {
|
||||
volume = l->data;
|
||||
@@ -2186,54 +2209,79 @@ mount_volume (GtkPlacesSidebar *sidebar, GVolume *volume)
|
||||
g_volume_mount (volume, 0, mount_op, NULL, volume_mount_cb, sidebar);
|
||||
}
|
||||
|
||||
static void
|
||||
open_selected_volume (GtkPlacesSidebar *sidebar,
|
||||
GtkTreeModel *model,
|
||||
GtkTreeIter *iter,
|
||||
GtkPlacesOpenFlags open_flags)
|
||||
{
|
||||
GDrive *drive;
|
||||
GVolume *volume;
|
||||
|
||||
gtk_tree_model_get (model, iter,
|
||||
PLACES_SIDEBAR_COLUMN_DRIVE, &drive,
|
||||
PLACES_SIDEBAR_COLUMN_VOLUME, &volume,
|
||||
-1);
|
||||
|
||||
if (volume != NULL && !sidebar->mounting) {
|
||||
sidebar->mounting = TRUE;
|
||||
|
||||
sidebar->go_to_after_mount_open_flags = open_flags;
|
||||
|
||||
mount_volume (sidebar, volume);
|
||||
} else if (volume == NULL && drive != NULL &&
|
||||
(g_drive_can_start (drive) || g_drive_can_start_degraded (drive))) {
|
||||
GMountOperation *mount_op;
|
||||
|
||||
mount_op = gtk_mount_operation_new (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (sidebar))));
|
||||
g_drive_start (drive, G_DRIVE_START_NONE, mount_op, NULL, drive_start_from_bookmark_cb, NULL);
|
||||
g_object_unref (mount_op);
|
||||
}
|
||||
|
||||
if (drive != NULL)
|
||||
g_object_unref (drive);
|
||||
|
||||
if (volume != NULL)
|
||||
g_object_unref (volume);
|
||||
}
|
||||
|
||||
static void
|
||||
open_selected_uri (GtkPlacesSidebar *sidebar,
|
||||
const gchar *uri,
|
||||
GtkPlacesOpenFlags open_flags)
|
||||
{
|
||||
GFile *location;
|
||||
|
||||
location = g_file_new_for_uri (uri);
|
||||
emit_open_location (sidebar, location, open_flags);
|
||||
g_object_unref (location);
|
||||
}
|
||||
|
||||
static void
|
||||
open_selected_bookmark (GtkPlacesSidebar *sidebar,
|
||||
GtkTreeModel *model,
|
||||
GtkTreeIter *iter,
|
||||
GtkPlacesOpenFlags open_flags)
|
||||
{
|
||||
GFile *location;
|
||||
char *uri;
|
||||
PlaceType place_type;
|
||||
|
||||
if (!iter) {
|
||||
return;
|
||||
}
|
||||
|
||||
gtk_tree_model_get (model, iter, PLACES_SIDEBAR_COLUMN_URI, &uri, -1);
|
||||
gtk_tree_model_get (model, iter,
|
||||
PLACES_SIDEBAR_COLUMN_URI, &uri,
|
||||
PLACES_SIDEBAR_COLUMN_ROW_TYPE, &place_type,
|
||||
-1);
|
||||
|
||||
if (uri != NULL) {
|
||||
location = g_file_new_for_uri (uri);
|
||||
emit_open_location (sidebar, location, open_flags);
|
||||
|
||||
g_object_unref (location);
|
||||
open_selected_uri (sidebar, uri, open_flags);
|
||||
g_free (uri);
|
||||
|
||||
} else if (place_type == PLACES_CONNECT_TO_SERVER) {
|
||||
emit_show_connect_to_server (sidebar);
|
||||
} else {
|
||||
GDrive *drive;
|
||||
GVolume *volume;
|
||||
|
||||
gtk_tree_model_get (model, iter,
|
||||
PLACES_SIDEBAR_COLUMN_DRIVE, &drive,
|
||||
PLACES_SIDEBAR_COLUMN_VOLUME, &volume,
|
||||
-1);
|
||||
|
||||
if (volume != NULL && !sidebar->mounting) {
|
||||
sidebar->mounting = TRUE;
|
||||
|
||||
sidebar->go_to_after_mount_open_flags = open_flags;
|
||||
|
||||
mount_volume (sidebar, volume);
|
||||
} else if (volume == NULL && drive != NULL &&
|
||||
(g_drive_can_start (drive) || g_drive_can_start_degraded (drive))) {
|
||||
GMountOperation *mount_op;
|
||||
|
||||
mount_op = gtk_mount_operation_new (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (sidebar))));
|
||||
g_drive_start (drive, G_DRIVE_START_NONE, mount_op, NULL, drive_start_from_bookmark_cb, sidebar);
|
||||
g_object_unref (mount_op);
|
||||
}
|
||||
|
||||
g_clear_object (&drive);
|
||||
g_clear_object (&volume);
|
||||
open_selected_volume (sidebar, model, iter, open_flags);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3161,9 +3209,10 @@ bookmarks_build_popup_menu (GtkPlacesSidebar *sidebar)
|
||||
else
|
||||
file = NULL;
|
||||
|
||||
emit_populate_popup (sidebar, GTK_MENU (sidebar->popup_menu), file);
|
||||
emit_populate_popup (sidebar, GTK_MENU (sidebar->popup_menu), file, sel_info.volume);
|
||||
|
||||
g_object_unref (file);
|
||||
if (file)
|
||||
g_object_unref (file);
|
||||
|
||||
free_selection_info (&sel_info);
|
||||
}
|
||||
@@ -3292,7 +3341,8 @@ bookmarks_button_release_event_cb (GtkWidget *widget,
|
||||
PLACES_SIDEBAR_COLUMN_ROW_TYPE, &row_type,
|
||||
-1);
|
||||
|
||||
if (row_type != PLACES_HEADING) {
|
||||
if (row_type != PLACES_HEADING
|
||||
&& row_type != PLACES_CONNECT_TO_SERVER) {
|
||||
bookmarks_popup_menu (sidebar, event);
|
||||
}
|
||||
}
|
||||
@@ -3477,7 +3527,9 @@ places_sidebar_sort_func (GtkTreeModel *model,
|
||||
|
||||
g_free (name_a);
|
||||
g_free (name_b);
|
||||
}
|
||||
} else if (place_type_a == PLACES_CONNECT_TO_SERVER) {
|
||||
retval = 1;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
@@ -3516,12 +3568,15 @@ hostname_proxy_new_cb (GObject *source_object,
|
||||
{
|
||||
GtkPlacesSidebar *sidebar = user_data;
|
||||
GError *error = NULL;
|
||||
GDBusProxy *proxy;
|
||||
|
||||
sidebar->hostnamed_proxy = g_dbus_proxy_new_for_bus_finish (res, &error);
|
||||
proxy = g_dbus_proxy_new_for_bus_finish (res, &error);
|
||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
return;
|
||||
|
||||
sidebar->hostnamed_proxy = proxy;
|
||||
g_clear_object (&sidebar->hostnamed_cancellable);
|
||||
|
||||
g_object_unref (sidebar);
|
||||
|
||||
if (error != NULL) {
|
||||
g_debug ("Failed to create D-Bus proxy: %s", error->message);
|
||||
g_error_free (error);
|
||||
@@ -3781,7 +3836,7 @@ gtk_places_sidebar_init (GtkPlacesSidebar *sidebar)
|
||||
"org.freedesktop.hostname1",
|
||||
sidebar->hostnamed_cancellable,
|
||||
hostname_proxy_new_cb,
|
||||
g_object_ref (sidebar));
|
||||
sidebar);
|
||||
|
||||
sidebar->drop_state = DROP_STATE_NORMAL;
|
||||
sidebar->new_bookmark_index = -1;
|
||||
@@ -3805,6 +3860,9 @@ gtk_places_sidebar_set_property (GObject *obj,
|
||||
case PROP_SHOW_DESKTOP:
|
||||
gtk_places_sidebar_set_show_desktop (sidebar, g_value_get_boolean (value));
|
||||
break;
|
||||
case PROP_SHOW_CONNECT_TO_SERVER:
|
||||
gtk_places_sidebar_set_show_connect_to_server (sidebar, g_value_get_boolean (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, property_id, pspec);
|
||||
break;
|
||||
@@ -3829,6 +3887,9 @@ gtk_places_sidebar_get_property (GObject *obj,
|
||||
case PROP_SHOW_DESKTOP:
|
||||
g_value_set_boolean (value, gtk_places_sidebar_get_show_desktop (sidebar));
|
||||
break;
|
||||
case PROP_SHOW_CONNECT_TO_SERVER:
|
||||
g_value_set_boolean (value, gtk_places_sidebar_get_show_connect_to_server (sidebar));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, property_id, pspec);
|
||||
break;
|
||||
@@ -3931,7 +3992,7 @@ gtk_places_sidebar_class_init (GtkPlacesSidebarClass *class)
|
||||
* location; for example, a file manager should show a list of files in
|
||||
* the specified location.
|
||||
*
|
||||
* Since: 3.8
|
||||
* Since: 3.10
|
||||
*/
|
||||
places_sidebar_signals [OPEN_LOCATION] =
|
||||
g_signal_new (I_("open-location"),
|
||||
@@ -3948,7 +4009,8 @@ gtk_places_sidebar_class_init (GtkPlacesSidebarClass *class)
|
||||
* GtkPlacesSidebar::populate-popup:
|
||||
* @sidebar: the object which received the signal.
|
||||
* @menu: a #GtkMenu.
|
||||
* @selected_item: #GFile with the item to which the menu should refer.
|
||||
* @selected_item: #GFile with the item to which the menu should refer, or #NULL in the case of a @selected_volume.
|
||||
* @selected_volume: #GVolume if the selected item is a volume, or #NULL if it is a file.
|
||||
*
|
||||
* The places sidebar emits this signal when the user invokes a contextual
|
||||
* menu on one of its items. In the signal handler, the application may
|
||||
@@ -3960,11 +4022,16 @@ gtk_places_sidebar_class_init (GtkPlacesSidebarClass *class)
|
||||
* gtk_places_sidebar_get_location() to get the file to which the item
|
||||
* refers.
|
||||
*
|
||||
* The @selected_item argument may be #NULL in case the selection refers to
|
||||
* a volume. In this case, @selected_volume will be non-NULL. In this case,
|
||||
* the calling application will have to g_object_ref() the @selected_volume and
|
||||
* keep it around for the purposes of its menu item's "activate" callback.
|
||||
*
|
||||
* The @menu and all its menu items are destroyed after the user
|
||||
* dismisses the menu. The menu is re-created (and thus, this signal is
|
||||
* emitted) every time the user activates the contextual menu.
|
||||
*
|
||||
* Since: 3.8
|
||||
* Since: 3.10
|
||||
*/
|
||||
places_sidebar_signals [POPULATE_POPUP] =
|
||||
g_signal_new (I_("populate-popup"),
|
||||
@@ -3972,8 +4039,9 @@ gtk_places_sidebar_class_init (GtkPlacesSidebarClass *class)
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (GtkPlacesSidebarClass, populate_popup),
|
||||
NULL, NULL,
|
||||
_gtk_marshal_VOID__OBJECT_OBJECT,
|
||||
G_TYPE_NONE, 2,
|
||||
_gtk_marshal_VOID__OBJECT_OBJECT_OBJECT,
|
||||
G_TYPE_NONE, 3,
|
||||
G_TYPE_OBJECT,
|
||||
G_TYPE_OBJECT,
|
||||
G_TYPE_OBJECT);
|
||||
|
||||
@@ -3988,7 +4056,7 @@ gtk_places_sidebar_class_init (GtkPlacesSidebarClass *class)
|
||||
* refer to mounting or unmounting media, for example, when a drive
|
||||
* cannot be started for some reason.
|
||||
*
|
||||
* Since: 3.8
|
||||
* Since: 3.10
|
||||
*/
|
||||
places_sidebar_signals [SHOW_ERROR_MESSAGE] =
|
||||
g_signal_new (I_("show-error-message"),
|
||||
@@ -4001,6 +4069,27 @@ gtk_places_sidebar_class_init (GtkPlacesSidebarClass *class)
|
||||
G_TYPE_STRING,
|
||||
G_TYPE_STRING);
|
||||
|
||||
/**
|
||||
* GtkPlacesSidebar::show-connect-to-server:
|
||||
* @sidebar: the object which received the signal.
|
||||
*
|
||||
* The places sidebar emits this signal when it needs the calling
|
||||
* application to present an way to connect directly to a network server.
|
||||
* For example, the application may bring up a dialog box asking for
|
||||
* a URL like "sftp://ftp.example.com". It is up to the application to create
|
||||
* the corresponding mount by using, for example, g_file_mount_enclosing_volume().
|
||||
*
|
||||
* Since: 3.10
|
||||
*/
|
||||
places_sidebar_signals [SHOW_CONNECT_TO_SERVER] =
|
||||
g_signal_new (I_("show-connect-to-server"),
|
||||
G_OBJECT_CLASS_TYPE (gobject_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (GtkPlacesSidebarClass, show_connect_to_server),
|
||||
NULL, NULL,
|
||||
_gtk_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
/**
|
||||
* GtkPlacesSidebar::drag-action-requested:
|
||||
* @sidebar: the object which received the signal.
|
||||
@@ -4022,7 +4111,7 @@ gtk_places_sidebar_class_init (GtkPlacesSidebarClass *class)
|
||||
* or #GDK_ACTION_MOVE, or 0 if no action is allowed here (i.e. drops
|
||||
* are not allowed in the specified @dest_file).
|
||||
*
|
||||
* Since: 3.8
|
||||
* Since: 3.10
|
||||
*/
|
||||
places_sidebar_signals [DRAG_ACTION_REQUESTED] =
|
||||
g_signal_new (I_("drag-action-requested"),
|
||||
@@ -4047,7 +4136,7 @@ gtk_places_sidebar_class_init (GtkPlacesSidebarClass *class)
|
||||
* Return value: the final drag action that the sidebar should pass to the drag side
|
||||
* of the drag-and-drop operation.
|
||||
*
|
||||
* Since: 3.8
|
||||
* Since: 3.10
|
||||
*/
|
||||
places_sidebar_signals [DRAG_ACTION_ASK] =
|
||||
g_signal_new (I_("drag-action-ask"),
|
||||
@@ -4072,7 +4161,7 @@ gtk_places_sidebar_class_init (GtkPlacesSidebarClass *class)
|
||||
* @source_file_list has the list of files that are dropped into it and
|
||||
* which should be copied/moved/etc. based on the specified @action.
|
||||
*
|
||||
* Since: 3.8
|
||||
* Since: 3.10
|
||||
*/
|
||||
places_sidebar_signals [DRAG_PERFORM_DROP] =
|
||||
g_signal_new (I_("drag-perform-drop"),
|
||||
@@ -4088,21 +4177,27 @@ gtk_places_sidebar_class_init (GtkPlacesSidebarClass *class)
|
||||
|
||||
properties[PROP_LOCATION] =
|
||||
g_param_spec_object ("location",
|
||||
P_("Location to select"),
|
||||
P_("Location to Select"),
|
||||
P_("The location to highlight in the sidebar"),
|
||||
G_TYPE_FILE,
|
||||
G_PARAM_READWRITE);
|
||||
properties[PROP_OPEN_FLAGS] =
|
||||
g_param_spec_flags ("open-flags",
|
||||
P_("The open modes supported for this widget"),
|
||||
P_("The set of open modes supported for this widget"),
|
||||
P_("Open Flags"),
|
||||
P_("Modes in which the calling application can open locations selected in the sidebar"),
|
||||
GTK_TYPE_PLACES_OPEN_FLAGS,
|
||||
GTK_PLACES_OPEN_NORMAL,
|
||||
G_PARAM_READWRITE);
|
||||
properties[PROP_SHOW_DESKTOP] =
|
||||
g_param_spec_boolean ("show-desktop",
|
||||
P_("Whether to show desktop"),
|
||||
P_("Whether the sidebar includes a builtin shortcut to the desktop folder"),
|
||||
P_("Show 'Desktop'"),
|
||||
P_("Whether the sidebar includes a builtin shortcut to the Desktop folder"),
|
||||
FALSE,
|
||||
G_PARAM_READWRITE);
|
||||
properties[PROP_SHOW_CONNECT_TO_SERVER] =
|
||||
g_param_spec_boolean ("show-connect-to-server",
|
||||
P_("Show 'Connect to Server'"),
|
||||
P_("Whether the sidebar includes a builtin shortcut to a 'Connect to server' dialog"),
|
||||
FALSE,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
@@ -4224,7 +4319,7 @@ shortcuts_model_new (GtkPlacesSidebar *sidebar)
|
||||
* Passing 0 for @flags will cause #GTK_PLACES_OPEN_NORMAL to always be sent
|
||||
* to callbacks for the "open-location" signal.
|
||||
*
|
||||
* Since: 3.8
|
||||
* Since: 3.10
|
||||
*/
|
||||
void
|
||||
gtk_places_sidebar_set_open_flags (GtkPlacesSidebar *sidebar, GtkPlacesOpenFlags flags)
|
||||
@@ -4256,7 +4351,7 @@ gtk_places_sidebar_get_open_flags (GtkPlacesSidebar *sidebar)
|
||||
* places, or it will unhighlight everything if the @location is not among the
|
||||
* places in the list.
|
||||
*
|
||||
* Since: 3.8
|
||||
* Since: 3.10
|
||||
*/
|
||||
void
|
||||
gtk_places_sidebar_set_location (GtkPlacesSidebar *sidebar, GFile *location)
|
||||
@@ -4316,7 +4411,7 @@ gtk_places_sidebar_set_location (GtkPlacesSidebar *sidebar, GFile *location)
|
||||
* Returns: (transfer full): a GFile with the selected location, or #NULL if nothing is visually
|
||||
* selected.
|
||||
*
|
||||
* Since: 3.8
|
||||
* Since: 3.10
|
||||
*/
|
||||
GFile *
|
||||
gtk_places_sidebar_get_location (GtkPlacesSidebar *sidebar)
|
||||
@@ -4351,7 +4446,7 @@ gtk_places_sidebar_get_location (GtkPlacesSidebar *sidebar)
|
||||
* An application may want to turn this on if the desktop environment actually supports the
|
||||
* notion of a desktop.
|
||||
*
|
||||
* Since: 3.8
|
||||
* Since: 3.10
|
||||
*/
|
||||
void
|
||||
gtk_places_sidebar_set_show_desktop (GtkPlacesSidebar *sidebar, gboolean show_desktop)
|
||||
@@ -4374,7 +4469,7 @@ gtk_places_sidebar_set_show_desktop (GtkPlacesSidebar *sidebar, gboolean show_de
|
||||
*
|
||||
* Return value: %TRUE if the sidebar will display a builtin shortcut to the desktop folder.
|
||||
*
|
||||
* Since: 3.8
|
||||
* Since: 3.10
|
||||
*/
|
||||
gboolean
|
||||
gtk_places_sidebar_get_show_desktop (GtkPlacesSidebar *sidebar)
|
||||
@@ -4384,6 +4479,48 @@ gtk_places_sidebar_get_show_desktop (GtkPlacesSidebar *sidebar)
|
||||
return sidebar->show_desktop;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_places_sidebar_set_show_connect_to_server:
|
||||
* @sidebar: a places sidebar
|
||||
* @show_connect_to_server: whether to show an item for the Connect to Server command
|
||||
*
|
||||
* Sets whether the @sidebar should show an item for connecting to a network server; this is off by default.
|
||||
* An application may want to turn this on if it implements a way for the user to connect
|
||||
* to network servers directly.
|
||||
*
|
||||
* Since: 3.10
|
||||
*/
|
||||
void
|
||||
gtk_places_sidebar_set_show_connect_to_server (GtkPlacesSidebar *sidebar, gboolean show_connect_to_server)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_PLACES_SIDEBAR (sidebar));
|
||||
|
||||
show_connect_to_server = !!show_connect_to_server;
|
||||
if (sidebar->show_connect_to_server != show_connect_to_server) {
|
||||
sidebar->show_connect_to_server = show_connect_to_server;
|
||||
update_places (sidebar);
|
||||
g_object_notify_by_pspec (G_OBJECT (sidebar), properties[PROP_SHOW_CONNECT_TO_SERVER]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_places_sidebar_get_show_connect_to_server:
|
||||
* @sidebar: a places sidebar
|
||||
*
|
||||
* Returns the value previously set with gtk_places_sidebar_set_show_connect_to_server()
|
||||
*
|
||||
* Return value: %TRUE if the sidebar will display a "Connect to Server" item.
|
||||
*
|
||||
* Since: 3.10
|
||||
*/
|
||||
gboolean
|
||||
gtk_places_sidebar_get_show_connect_to_server (GtkPlacesSidebar *sidebar)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_PLACES_SIDEBAR (sidebar), FALSE);
|
||||
|
||||
return sidebar->show_connect_to_server;
|
||||
}
|
||||
|
||||
static GSList *
|
||||
find_shortcut_link (GtkPlacesSidebar *sidebar, GFile *location)
|
||||
{
|
||||
@@ -4416,7 +4553,7 @@ find_shortcut_link (GtkPlacesSidebar *sidebar, GFile *location)
|
||||
* is called multiple times with different locations, then they are added
|
||||
* to the sidebar's list in the same order as the function is called.
|
||||
*
|
||||
* Since: 3.8
|
||||
* Since: 3.10
|
||||
*/
|
||||
void
|
||||
gtk_places_sidebar_add_shortcut (GtkPlacesSidebar *sidebar, GFile *location)
|
||||
@@ -4439,7 +4576,7 @@ gtk_places_sidebar_add_shortcut (GtkPlacesSidebar *sidebar, GFile *location)
|
||||
* inserted with gtk_places_sidebar_add_shortcut(). If the @location is not a
|
||||
* shortcut in the sidebar, then nothing is done.
|
||||
*
|
||||
* Since: 3.8
|
||||
* Since: 3.10
|
||||
*/
|
||||
void
|
||||
gtk_places_sidebar_remove_shortcut (GtkPlacesSidebar *sidebar, GFile *location)
|
||||
@@ -4472,7 +4609,7 @@ gtk_places_sidebar_remove_shortcut (GtkPlacesSidebar *sidebar, GFile *location)
|
||||
* g_slist_free_full (list, (GDestroyNotify) g_object_unref);
|
||||
* ]|
|
||||
*
|
||||
* Since: 3.8
|
||||
* Since: 3.10
|
||||
*/
|
||||
GSList *
|
||||
gtk_places_sidebar_list_shortcuts (GtkPlacesSidebar *sidebar)
|
||||
@@ -4495,7 +4632,7 @@ gtk_places_sidebar_list_shortcuts (GtkPlacesSidebar *sidebar)
|
||||
* #NULL if no such index exist. Note that the indices start at 0, even though
|
||||
* the file chooser starts them with the keyboard shortcut "Alt-1".
|
||||
*
|
||||
* Since: 3.8
|
||||
* Since: 3.10
|
||||
*/
|
||||
GFile *
|
||||
gtk_places_sidebar_get_nth_bookmark (GtkPlacesSidebar *sidebar, int n)
|
||||
|
||||
@@ -77,23 +77,33 @@ typedef enum {
|
||||
GTK_PLACES_OPEN_NEW_WINDOW = 1 << 2
|
||||
} GtkPlacesOpenFlags;
|
||||
|
||||
GType gtk_places_sidebar_get_type (void);
|
||||
GtkWidget *gtk_places_sidebar_new (void);
|
||||
GType gtk_places_sidebar_get_type (void) G_GNUC_CONST;
|
||||
GtkWidget * gtk_places_sidebar_new (void);
|
||||
|
||||
GtkPlacesOpenFlags gtk_places_sidebar_get_open_flags (GtkPlacesSidebar *sidebar);
|
||||
void gtk_places_sidebar_set_open_flags (GtkPlacesSidebar *sidebar, GtkPlacesOpenFlags flags);
|
||||
GtkPlacesOpenFlags gtk_places_sidebar_get_open_flags (GtkPlacesSidebar *sidebar);
|
||||
void gtk_places_sidebar_set_open_flags (GtkPlacesSidebar *sidebar,
|
||||
GtkPlacesOpenFlags flags);
|
||||
|
||||
GFile *gtk_places_sidebar_get_location (GtkPlacesSidebar *sidebar);
|
||||
void gtk_places_sidebar_set_location (GtkPlacesSidebar *sidebar, GFile *location);
|
||||
GFile * gtk_places_sidebar_get_location (GtkPlacesSidebar *sidebar);
|
||||
void gtk_places_sidebar_set_location (GtkPlacesSidebar *sidebar,
|
||||
GFile *location);
|
||||
|
||||
gboolean gtk_places_sidebar_get_show_desktop (GtkPlacesSidebar *sidebar);
|
||||
void gtk_places_sidebar_set_show_desktop (GtkPlacesSidebar *sidebar, gboolean show_desktop);
|
||||
gboolean gtk_places_sidebar_get_show_desktop (GtkPlacesSidebar *sidebar);
|
||||
void gtk_places_sidebar_set_show_desktop (GtkPlacesSidebar *sidebar,
|
||||
gboolean show_desktop);
|
||||
|
||||
void gtk_places_sidebar_add_shortcut (GtkPlacesSidebar *sidebar, GFile *location);
|
||||
void gtk_places_sidebar_remove_shortcut (GtkPlacesSidebar *sidebar, GFile *location);
|
||||
GSList *gtk_places_sidebar_list_shortcuts (GtkPlacesSidebar *sidebar);
|
||||
gboolean gtk_places_sidebar_get_show_connect_to_server (GtkPlacesSidebar *sidebar);
|
||||
void gtk_places_sidebar_set_show_connect_to_server (GtkPlacesSidebar *sidebar,
|
||||
gboolean show_connect_to_server);
|
||||
|
||||
GFile *gtk_places_sidebar_get_nth_bookmark (GtkPlacesSidebar *sidebar, int n);
|
||||
void gtk_places_sidebar_add_shortcut (GtkPlacesSidebar *sidebar,
|
||||
GFile *location);
|
||||
void gtk_places_sidebar_remove_shortcut (GtkPlacesSidebar *sidebar,
|
||||
GFile *location);
|
||||
GSList * gtk_places_sidebar_list_shortcuts (GtkPlacesSidebar *sidebar);
|
||||
|
||||
GFile * gtk_places_sidebar_get_nth_bookmark (GtkPlacesSidebar *sidebar,
|
||||
gint n);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@@ -37,6 +37,8 @@ G_BEGIN_DECLS
|
||||
#define GTK_PARAM_WRITABLE G_PARAM_WRITABLE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB
|
||||
#define GTK_PARAM_READWRITE G_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB
|
||||
|
||||
#define OPPOSITE_ORIENTATION(_orientation) (1 - (_orientation))
|
||||
|
||||
#ifdef G_DISABLE_CAST_CHECKS
|
||||
/* This is true for debug no and minimum */
|
||||
#define gtk_internal_return_if_fail(__expr) G_STMT_START{ (void)0; }G_STMT_END
|
||||
|
||||
@@ -903,6 +903,7 @@ gtk_radio_button_draw_indicator (GtkCheckButton *check_button,
|
||||
gint indicator_size, indicator_spacing;
|
||||
gint focus_width;
|
||||
gint focus_pad;
|
||||
gint baseline;
|
||||
guint border_width;
|
||||
gboolean interior_focus;
|
||||
|
||||
@@ -923,9 +924,14 @@ gtk_radio_button_draw_indicator (GtkCheckButton *check_button,
|
||||
_gtk_check_button_get_props (check_button, &indicator_size, &indicator_spacing);
|
||||
|
||||
gtk_widget_get_allocation (widget, &allocation);
|
||||
baseline = gtk_widget_get_allocated_baseline (widget);
|
||||
|
||||
x = indicator_spacing + border_width;
|
||||
y = (allocation.height - indicator_size) / 2;
|
||||
if (baseline == -1)
|
||||
y = (allocation.height - indicator_size) / 2;
|
||||
else
|
||||
y = CLAMP (baseline - indicator_size * button->priv->baseline_align,
|
||||
0, allocation.height - indicator_size);
|
||||
|
||||
child = gtk_bin_get_child (GTK_BIN (check_button));
|
||||
if (!interior_focus || !(child && gtk_widget_get_visible (child)))
|
||||
|
||||
@@ -0,0 +1,896 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* Copyright (c) 2013 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program 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 program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Author: Alexander Larsson <alexl@redhat.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "gtkrevealer.h"
|
||||
#include <gdk/gdk.h>
|
||||
#include "gtktypebuiltins.h"
|
||||
#include "gtkprivate.h"
|
||||
#include "gtkintl.h"
|
||||
#include <math.h>
|
||||
|
||||
/**
|
||||
* SECTION:gtkrevealer
|
||||
* @Short_description: Hide and show with animation
|
||||
* @Title: GtkRevealer
|
||||
* @See_also: #GtkExpander
|
||||
*
|
||||
* The GtkRevealer widget is a container which animates
|
||||
* the transition of its child from invisible to visible.
|
||||
*
|
||||
* The style of transition can be controlled with
|
||||
* gtk_revealer_set_transition_type().
|
||||
*
|
||||
* The GtkRevealer widget was added in GTK+ 3.10.
|
||||
*/
|
||||
|
||||
/**
|
||||
* GtkRevealerTransitionType:
|
||||
* @GTK_REVEALER_TRANSITION_TYPE_NONE: No transition
|
||||
* @GTK_REVEALER_TRANSITION_TYPE_CROSSFADE: Fade in
|
||||
* @GTK_REVEALER_TRANSITION_TYPE_SLIDE_RIGHT: Slide in from the left
|
||||
* @GTK_REVEALER_TRANSITION_TYPE_SLIDE_LEFT: Slide in from the right
|
||||
* @GTK_REVEALER_TRANSITION_TYPE_SLIDE_UP: Slide in from the bottom
|
||||
* @GTK_REVEALER_TRANSITION_TYPE_SLIDE_DOWN: Slide in from the top
|
||||
*
|
||||
* These enumeration values describe the possible transitions
|
||||
* when the child of a #GtkRevealer widget is shown or hidden.
|
||||
*/
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_TRANSITION_TYPE,
|
||||
PROP_TRANSITION_DURATION,
|
||||
PROP_REVEAL_CHILD,
|
||||
PROP_CHILD_REVEALED
|
||||
};
|
||||
|
||||
struct _GtkRevealerPrivate {
|
||||
GtkRevealerTransitionType transition_type;
|
||||
guint transition_duration;
|
||||
|
||||
GdkWindow* bin_window;
|
||||
GdkWindow* view_window;
|
||||
|
||||
gdouble current_pos;
|
||||
gdouble source_pos;
|
||||
gdouble target_pos;
|
||||
|
||||
guint tick_id;
|
||||
gint64 start_time;
|
||||
gint64 end_time;
|
||||
};
|
||||
|
||||
|
||||
static void gtk_revealer_real_realize (GtkWidget *widget);
|
||||
static void gtk_revealer_real_unrealize (GtkWidget *widget);
|
||||
static void gtk_revealer_real_add (GtkContainer *widget,
|
||||
GtkWidget *child);
|
||||
static void gtk_revealer_real_style_updated (GtkWidget *widget);
|
||||
static void gtk_revealer_real_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *allocation);
|
||||
static void gtk_revealer_real_map (GtkWidget *widget);
|
||||
static void gtk_revealer_real_unmap (GtkWidget *widget);
|
||||
static gboolean gtk_revealer_real_draw (GtkWidget *widget,
|
||||
cairo_t *cr);
|
||||
static void gtk_revealer_real_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum_height,
|
||||
gint *natural_height);
|
||||
static void gtk_revealer_real_get_preferred_height_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum_height,
|
||||
gint *natural_height);
|
||||
static void gtk_revealer_real_get_preferred_width (GtkWidget *widget,
|
||||
gint *minimum_width,
|
||||
gint *natural_width);
|
||||
static void gtk_revealer_real_get_preferred_width_for_height (GtkWidget *widget,
|
||||
gint height,
|
||||
gint *minimum_width,
|
||||
gint *natural_width);
|
||||
|
||||
G_DEFINE_TYPE (GtkRevealer, gtk_revealer, GTK_TYPE_BIN);
|
||||
|
||||
|
||||
static void
|
||||
gtk_revealer_init (GtkRevealer *revealer)
|
||||
{
|
||||
GtkRevealerPrivate *priv;
|
||||
|
||||
priv = G_TYPE_INSTANCE_GET_PRIVATE (revealer, GTK_TYPE_REVEALER, GtkRevealerPrivate);
|
||||
revealer->priv = priv;
|
||||
|
||||
priv->transition_type = GTK_REVEALER_TRANSITION_TYPE_SLIDE_DOWN;
|
||||
priv->transition_duration = 250;
|
||||
priv->current_pos = 0.0;
|
||||
priv->target_pos = 0.0;
|
||||
|
||||
gtk_widget_set_has_window ((GtkWidget*) revealer, TRUE);
|
||||
gtk_widget_set_redraw_on_allocate ((GtkWidget*) revealer, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_revealer_finalize (GObject *obj)
|
||||
{
|
||||
GtkRevealer *revealer = GTK_REVEALER (obj);
|
||||
GtkRevealerPrivate *priv = revealer->priv;
|
||||
|
||||
if (priv->tick_id != 0)
|
||||
gtk_widget_remove_tick_callback (GTK_WIDGET (revealer), priv->tick_id);
|
||||
priv->tick_id = 0;
|
||||
|
||||
G_OBJECT_CLASS (gtk_revealer_parent_class)->finalize (obj);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_revealer_get_property (GObject *object,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkRevealer *revealer = GTK_REVEALER (object);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_TRANSITION_TYPE:
|
||||
g_value_set_enum (value, gtk_revealer_get_transition_type (revealer));
|
||||
break;
|
||||
case PROP_TRANSITION_DURATION:
|
||||
g_value_set_uint (value, gtk_revealer_get_transition_duration (revealer));
|
||||
break;
|
||||
case PROP_REVEAL_CHILD:
|
||||
g_value_set_boolean (value, gtk_revealer_get_reveal_child (revealer));
|
||||
break;
|
||||
case PROP_CHILD_REVEALED:
|
||||
g_value_set_boolean (value, gtk_revealer_get_child_revealed (revealer));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_revealer_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkRevealer *revealer = GTK_REVEALER (object);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_TRANSITION_TYPE:
|
||||
gtk_revealer_set_transition_type (revealer, g_value_get_enum (value));
|
||||
break;
|
||||
case PROP_TRANSITION_DURATION:
|
||||
gtk_revealer_set_transition_duration (revealer, g_value_get_uint (value));
|
||||
break;
|
||||
case PROP_REVEAL_CHILD:
|
||||
gtk_revealer_set_reveal_child (revealer, g_value_get_boolean (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_revealer_class_init (GtkRevealerClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
|
||||
GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
|
||||
|
||||
object_class->get_property = gtk_revealer_get_property;
|
||||
object_class->set_property = gtk_revealer_set_property;
|
||||
object_class->finalize = gtk_revealer_finalize;
|
||||
|
||||
widget_class->realize = gtk_revealer_real_realize;
|
||||
widget_class->unrealize = gtk_revealer_real_unrealize;
|
||||
widget_class->style_updated = gtk_revealer_real_style_updated;
|
||||
widget_class->size_allocate = gtk_revealer_real_size_allocate;
|
||||
widget_class->map = gtk_revealer_real_map;
|
||||
widget_class->unmap = gtk_revealer_real_unmap;
|
||||
widget_class->draw = gtk_revealer_real_draw;
|
||||
widget_class->get_preferred_height = gtk_revealer_real_get_preferred_height;
|
||||
widget_class->get_preferred_height_for_width = gtk_revealer_real_get_preferred_height_for_width;
|
||||
widget_class->get_preferred_width = gtk_revealer_real_get_preferred_width;
|
||||
widget_class->get_preferred_width_for_height = gtk_revealer_real_get_preferred_width_for_height;
|
||||
|
||||
container_class->add = gtk_revealer_real_add;
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_TRANSITION_TYPE,
|
||||
g_param_spec_enum ("transition-type",
|
||||
P_("Transition type"),
|
||||
P_("The type of animation used to transition"),
|
||||
GTK_TYPE_REVEALER_TRANSITION_TYPE,
|
||||
GTK_REVEALER_TRANSITION_TYPE_SLIDE_DOWN,
|
||||
GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT));
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_TRANSITION_DURATION,
|
||||
g_param_spec_uint ("transition-duration",
|
||||
P_("Transition duration"),
|
||||
P_("The animation duration, in milliseconds"),
|
||||
0, G_MAXUINT,
|
||||
250,
|
||||
GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT));
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_REVEAL_CHILD,
|
||||
g_param_spec_boolean ("reveal-child",
|
||||
P_("Reveal Child"),
|
||||
P_("Whether the container should reveal the child"),
|
||||
FALSE,
|
||||
GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT));
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_CHILD_REVEALED,
|
||||
g_param_spec_boolean ("child-revealed",
|
||||
P_("Child Revealed"),
|
||||
P_("Whether the child is revealed and the animation target reached"),
|
||||
FALSE,
|
||||
G_PARAM_READABLE));
|
||||
|
||||
g_type_class_add_private (klass, sizeof (GtkRevealerPrivate));
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
gtk_revealer_new (void)
|
||||
{
|
||||
return g_object_new (GTK_TYPE_REVEALER, NULL);
|
||||
}
|
||||
|
||||
static GtkRevealerTransitionType
|
||||
effective_transition (GtkRevealer *revealer)
|
||||
{
|
||||
GtkRevealerPrivate *priv = revealer->priv;
|
||||
|
||||
if (gtk_widget_get_direction (GTK_WIDGET (revealer)) == GTK_TEXT_DIR_RTL)
|
||||
{
|
||||
if (priv->transition_type == GTK_REVEALER_TRANSITION_TYPE_SLIDE_LEFT)
|
||||
return GTK_REVEALER_TRANSITION_TYPE_SLIDE_RIGHT;
|
||||
else if (priv->transition_type == GTK_REVEALER_TRANSITION_TYPE_SLIDE_RIGHT)
|
||||
return GTK_REVEALER_TRANSITION_TYPE_SLIDE_LEFT;
|
||||
}
|
||||
|
||||
return priv->transition_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_revealer_get_child_allocation (GtkRevealer *revealer,
|
||||
GtkAllocation *allocation,
|
||||
GtkAllocation *child_allocation)
|
||||
{
|
||||
GtkWidget *child;
|
||||
GtkRevealerTransitionType transition;
|
||||
|
||||
g_return_if_fail (revealer != NULL);
|
||||
g_return_if_fail (allocation != NULL);
|
||||
|
||||
child_allocation->x = 0;
|
||||
child_allocation->y = 0;
|
||||
child_allocation->width = allocation->width;
|
||||
child_allocation->height = allocation->height;
|
||||
|
||||
child = gtk_bin_get_child (GTK_BIN (revealer));
|
||||
if (child != NULL && gtk_widget_get_visible (child))
|
||||
{
|
||||
transition = effective_transition (revealer);
|
||||
if (transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_LEFT ||
|
||||
transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_RIGHT)
|
||||
gtk_widget_get_preferred_width_for_height (child, child_allocation->height, NULL,
|
||||
&child_allocation->width);
|
||||
else
|
||||
gtk_widget_get_preferred_height_for_width (child, child_allocation->width, NULL,
|
||||
&child_allocation->height);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_revealer_real_realize (GtkWidget *widget)
|
||||
{
|
||||
GtkRevealer *revealer = GTK_REVEALER (widget);
|
||||
GtkRevealerPrivate *priv = revealer->priv;
|
||||
GtkAllocation allocation;
|
||||
GdkWindowAttr attributes = { 0 };
|
||||
GdkWindowAttributesType attributes_mask;
|
||||
GtkAllocation child_allocation;
|
||||
GtkWidget *child;
|
||||
GtkStyleContext *context;
|
||||
GtkRevealerTransitionType transition;
|
||||
|
||||
gtk_widget_set_realized (widget, TRUE);
|
||||
|
||||
gtk_widget_get_allocation (widget, &allocation);
|
||||
|
||||
attributes.x = allocation.x;
|
||||
attributes.y = allocation.y;
|
||||
attributes.width = allocation.width;
|
||||
attributes.height = allocation.height;
|
||||
attributes.window_type = GDK_WINDOW_CHILD;
|
||||
attributes.wclass = GDK_INPUT_OUTPUT;
|
||||
attributes.visual = gtk_widget_get_visual (widget);
|
||||
attributes.event_mask =
|
||||
gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK;
|
||||
attributes_mask = (GDK_WA_X | GDK_WA_Y) | GDK_WA_VISUAL;
|
||||
|
||||
priv->view_window =
|
||||
gdk_window_new (gtk_widget_get_parent_window ((GtkWidget*) revealer),
|
||||
&attributes, attributes_mask);
|
||||
gtk_widget_set_window (widget, priv->view_window);
|
||||
gtk_widget_register_window (widget, priv->view_window);
|
||||
|
||||
gtk_revealer_get_child_allocation (revealer, &allocation, &child_allocation);
|
||||
|
||||
attributes.x = 0;
|
||||
attributes.y = 0;
|
||||
attributes.width = child_allocation.width;
|
||||
attributes.height = child_allocation.height;
|
||||
|
||||
transition = effective_transition (revealer);
|
||||
if (transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_DOWN)
|
||||
attributes.y = allocation.height - child_allocation.height;
|
||||
else if (transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_RIGHT)
|
||||
attributes.x = allocation.width - child_allocation.width;
|
||||
|
||||
priv->bin_window =
|
||||
gdk_window_new (priv->view_window, &attributes, attributes_mask);
|
||||
gtk_widget_register_window (widget, priv->bin_window);
|
||||
|
||||
child = gtk_bin_get_child (GTK_BIN (revealer));
|
||||
if (child != NULL)
|
||||
gtk_widget_set_parent_window (child, priv->bin_window);
|
||||
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
gtk_style_context_set_background (context, priv->view_window);
|
||||
gtk_style_context_set_background (context, priv->bin_window);
|
||||
gdk_window_show (priv->bin_window);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_revealer_real_unrealize (GtkWidget *widget)
|
||||
{
|
||||
GtkRevealer *revealer = GTK_REVEALER (widget);
|
||||
GtkRevealerPrivate *priv = revealer->priv;
|
||||
|
||||
gtk_widget_unregister_window (widget, priv->bin_window);
|
||||
gdk_window_destroy (priv->bin_window);
|
||||
priv->view_window = NULL;
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_revealer_parent_class)->unrealize (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_revealer_real_add (GtkContainer *container,
|
||||
GtkWidget *child)
|
||||
{
|
||||
GtkRevealer *revealer = GTK_REVEALER (container);
|
||||
GtkRevealerPrivate *priv = revealer->priv;
|
||||
|
||||
g_return_if_fail (child != NULL);
|
||||
|
||||
gtk_widget_set_parent_window (child, priv->bin_window);
|
||||
gtk_widget_set_child_visible (child, priv->current_pos != 0.0);
|
||||
|
||||
GTK_CONTAINER_CLASS (gtk_revealer_parent_class)->add (container, child);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_revealer_real_style_updated (GtkWidget *widget)
|
||||
{
|
||||
GtkRevealer *revealer = GTK_REVEALER (widget);
|
||||
GtkRevealerPrivate *priv = revealer->priv;
|
||||
GtkStyleContext* context;
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_revealer_parent_class)->style_updated (widget);
|
||||
|
||||
if (gtk_widget_get_realized (widget))
|
||||
{
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
gtk_style_context_set_background (context, priv->bin_window);
|
||||
gtk_style_context_set_background (context, priv->view_window);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_revealer_real_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *allocation)
|
||||
{
|
||||
GtkRevealer *revealer = GTK_REVEALER (widget);
|
||||
GtkRevealerPrivate *priv = revealer->priv;
|
||||
GtkAllocation child_allocation;
|
||||
GtkWidget *child;
|
||||
gboolean window_visible;
|
||||
int bin_x, bin_y;
|
||||
GtkRevealerTransitionType transition;
|
||||
|
||||
g_return_if_fail (allocation != NULL);
|
||||
|
||||
gtk_widget_set_allocation (widget, allocation);
|
||||
gtk_revealer_get_child_allocation (revealer, allocation, &child_allocation);
|
||||
|
||||
child = gtk_bin_get_child (GTK_BIN (revealer));
|
||||
if (child != NULL && gtk_widget_get_visible (child))
|
||||
gtk_widget_size_allocate (child, &child_allocation);
|
||||
|
||||
if (gtk_widget_get_realized (widget))
|
||||
{
|
||||
if (gtk_widget_get_mapped (widget))
|
||||
{
|
||||
window_visible = allocation->width > 0 && allocation->height > 0;
|
||||
|
||||
if (!window_visible && gdk_window_is_visible (priv->view_window))
|
||||
gdk_window_hide (priv->view_window);
|
||||
|
||||
if (window_visible && !gdk_window_is_visible (priv->view_window))
|
||||
gdk_window_show (priv->view_window);
|
||||
}
|
||||
|
||||
gdk_window_move_resize (priv->view_window,
|
||||
allocation->x, allocation->y,
|
||||
allocation->width, allocation->height);
|
||||
|
||||
bin_x = 0;
|
||||
bin_y = 0;
|
||||
transition = effective_transition (revealer);
|
||||
if (transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_DOWN)
|
||||
bin_y = allocation->height - child_allocation.height;
|
||||
else if (transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_RIGHT)
|
||||
bin_x = allocation->width - child_allocation.width;
|
||||
|
||||
gdk_window_move_resize (priv->bin_window,
|
||||
bin_x, bin_y,
|
||||
child_allocation.width, child_allocation.height);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_revealer_set_position (GtkRevealer *revealer,
|
||||
gdouble pos)
|
||||
{
|
||||
GtkRevealerPrivate *priv = revealer->priv;
|
||||
gboolean new_visible;
|
||||
GtkWidget *child;
|
||||
GtkRevealerTransitionType transition;
|
||||
|
||||
priv->current_pos = pos;
|
||||
|
||||
/* We check target_pos here too, because we want to ensure we set
|
||||
* child_visible immediately when starting a reveal operation
|
||||
* otherwise the child widgets will not be properly realized
|
||||
* after the reveal returns.
|
||||
*/
|
||||
new_visible = priv->current_pos != 0.0 || priv->target_pos != 0.0;
|
||||
|
||||
child = gtk_bin_get_child (GTK_BIN (revealer));
|
||||
if (child != NULL &&
|
||||
new_visible != gtk_widget_get_child_visible (child))
|
||||
gtk_widget_set_child_visible (child, new_visible);
|
||||
|
||||
transition = effective_transition (revealer);
|
||||
if (transition == GTK_REVEALER_TRANSITION_TYPE_CROSSFADE)
|
||||
{
|
||||
gtk_widget_set_opacity (GTK_WIDGET (revealer), priv->current_pos);
|
||||
gtk_widget_queue_draw (GTK_WIDGET (revealer));
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_widget_queue_resize (GTK_WIDGET (revealer));
|
||||
}
|
||||
|
||||
if (priv->current_pos == priv->target_pos)
|
||||
g_object_notify (G_OBJECT (revealer), "child-revealed");
|
||||
}
|
||||
|
||||
static gdouble
|
||||
ease_out_quad (gdouble t, gdouble d)
|
||||
{
|
||||
gdouble p = t / d;
|
||||
return ((-1.0) * p) * (p - 2);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_revealer_animate_step (GtkRevealer *revealer,
|
||||
gint64 now)
|
||||
{
|
||||
GtkRevealerPrivate *priv = revealer->priv;
|
||||
gdouble t;
|
||||
|
||||
t = 1.0;
|
||||
if (now < priv->end_time)
|
||||
t = (now - priv->start_time) / (gdouble) (priv->end_time - priv->start_time);
|
||||
t = ease_out_quad (t, 1.0);
|
||||
|
||||
gtk_revealer_set_position (revealer,
|
||||
priv->source_pos + (t * (priv->target_pos - priv->source_pos)));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_revealer_animate_cb (GtkRevealer *revealer,
|
||||
GdkFrameClock *frame_clock,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkRevealerPrivate *priv = revealer->priv;
|
||||
gint64 now;
|
||||
|
||||
now = gdk_frame_clock_get_frame_time (frame_clock);
|
||||
gtk_revealer_animate_step (revealer, now);
|
||||
if (priv->current_pos == priv->target_pos)
|
||||
{
|
||||
priv->tick_id = 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_revealer_start_animation (GtkRevealer *revealer,
|
||||
gdouble target)
|
||||
{
|
||||
GtkRevealerPrivate *priv = revealer->priv;
|
||||
GtkWidget *widget = GTK_WIDGET (revealer);
|
||||
GtkRevealerTransitionType transition;
|
||||
|
||||
if (priv->target_pos == target)
|
||||
return;
|
||||
|
||||
priv->target_pos = target;
|
||||
g_object_notify (G_OBJECT (revealer), "reveal-child");
|
||||
|
||||
transition = effective_transition (revealer);
|
||||
if (gtk_widget_get_mapped (widget) &&
|
||||
priv->transition_duration != 0 &&
|
||||
transition != GTK_REVEALER_TRANSITION_TYPE_NONE)
|
||||
{
|
||||
priv->source_pos = priv->current_pos;
|
||||
priv->start_time = gdk_frame_clock_get_frame_time (gtk_widget_get_frame_clock (widget));
|
||||
priv->end_time = priv->start_time + (priv->transition_duration * 1000);
|
||||
if (priv->tick_id == 0)
|
||||
priv->tick_id =
|
||||
gtk_widget_add_tick_callback (widget, (GtkTickCallback)gtk_revealer_animate_cb, revealer, NULL);
|
||||
gtk_revealer_animate_step (revealer, priv->start_time);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_revealer_set_position (revealer, target);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_revealer_stop_animation (GtkRevealer *revealer)
|
||||
{
|
||||
GtkRevealerPrivate *priv = revealer->priv;
|
||||
|
||||
priv->current_pos = priv->target_pos;
|
||||
if (priv->tick_id != 0)
|
||||
{
|
||||
gtk_widget_remove_tick_callback (GTK_WIDGET (revealer), priv->tick_id);
|
||||
priv->tick_id = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_revealer_real_map (GtkWidget *widget)
|
||||
{
|
||||
GtkRevealer *revealer = GTK_REVEALER (widget);
|
||||
GtkRevealerPrivate *priv = revealer->priv;
|
||||
GtkAllocation allocation;
|
||||
|
||||
if (!gtk_widget_get_mapped (widget))
|
||||
{
|
||||
gtk_widget_get_allocation (widget, &allocation);
|
||||
|
||||
if (allocation.width > 0 && allocation.height > 0)
|
||||
gdk_window_show (priv->view_window);
|
||||
|
||||
gtk_revealer_start_animation (revealer, priv->target_pos);
|
||||
}
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_revealer_parent_class)->map (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_revealer_real_unmap (GtkWidget *widget)
|
||||
{
|
||||
GtkRevealer *revealer = GTK_REVEALER (widget);
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_revealer_parent_class)->unmap (widget);
|
||||
|
||||
gtk_revealer_stop_animation (revealer);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_revealer_real_draw (GtkWidget *widget,
|
||||
cairo_t *cr)
|
||||
{
|
||||
GtkRevealer *revealer = GTK_REVEALER (widget);
|
||||
GtkRevealerPrivate *priv = revealer->priv;
|
||||
|
||||
if (gtk_cairo_should_draw_window (cr, priv->bin_window))
|
||||
GTK_WIDGET_CLASS (gtk_revealer_parent_class)->draw (widget, cr);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_revealer_set_reveal_child:
|
||||
* @revealer: a #GtkRevealer
|
||||
* @reveal_child: %TRUE to reveal the child
|
||||
*
|
||||
* Tells the #GtkRevealer to reveal or conceal its child.
|
||||
*
|
||||
* The transition will be animated with the current
|
||||
* transition type of @revealer.
|
||||
*
|
||||
* Since: 3.10
|
||||
*/
|
||||
void
|
||||
gtk_revealer_set_reveal_child (GtkRevealer *revealer,
|
||||
gboolean reveal_child)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_REVEALER (revealer));
|
||||
|
||||
if (reveal_child)
|
||||
gtk_revealer_start_animation (revealer, 1.0);
|
||||
else
|
||||
gtk_revealer_start_animation (revealer, 0.0);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_revealer_get_reveal_child:
|
||||
* @revealer: a #GtkRevealer
|
||||
*
|
||||
* Returns whether the child is currently
|
||||
* revealed. See gtk_revealer_set_reveal_child().
|
||||
*
|
||||
* This function returns %TRUE as soon as the transition
|
||||
* is to the revealed state is started. To learn whether
|
||||
* the child is fully revealed (ie the transition is completed),
|
||||
* use gtk_revealer_get_child_revealed().
|
||||
*
|
||||
* Return value: %TRUE if the child is revealed.
|
||||
*
|
||||
* Since: 3.10
|
||||
*/
|
||||
gboolean
|
||||
gtk_revealer_get_reveal_child (GtkRevealer *revealer)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_REVEALER (revealer), FALSE);
|
||||
|
||||
return revealer->priv->target_pos != 0.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_revealer_get_child_revealed:
|
||||
* @revealer: a #GtkRevealer
|
||||
*
|
||||
* Returns whether the child is fully revealed, ie wether
|
||||
* the transition to the revealed state is completed.
|
||||
*
|
||||
* Return value: %TRUE if the child is fully revealed
|
||||
*
|
||||
* Since: 3.10
|
||||
*/
|
||||
gboolean
|
||||
gtk_revealer_get_child_revealed (GtkRevealer *revealer)
|
||||
{
|
||||
gboolean animation_finished = (revealer->priv->target_pos == revealer->priv->current_pos);
|
||||
gboolean reveal_child = gtk_revealer_get_reveal_child (revealer);
|
||||
|
||||
if (animation_finished)
|
||||
return reveal_child;
|
||||
else
|
||||
return !reveal_child;
|
||||
}
|
||||
|
||||
/* These all report only the natural size, ignoring the minimal size,
|
||||
* because its not really possible to allocate the right size during
|
||||
* animation if the child size can change (without the child
|
||||
* re-arranging itself during the animation).
|
||||
*/
|
||||
|
||||
static void
|
||||
gtk_revealer_real_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum_height_out,
|
||||
gint *natural_height_out)
|
||||
{
|
||||
GtkRevealer *revealer = GTK_REVEALER (widget);
|
||||
GtkRevealerPrivate *priv = revealer->priv;
|
||||
gint minimum_height;
|
||||
gint natural_height;
|
||||
GtkRevealerTransitionType transition;
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_revealer_parent_class)->get_preferred_height (widget, &minimum_height, &natural_height);
|
||||
|
||||
transition = effective_transition (revealer);
|
||||
if (transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_UP ||
|
||||
transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_DOWN)
|
||||
natural_height = round (natural_height * priv->current_pos);
|
||||
|
||||
minimum_height = natural_height;
|
||||
|
||||
if (minimum_height_out)
|
||||
*minimum_height_out = minimum_height;
|
||||
if (natural_height_out)
|
||||
*natural_height_out = natural_height;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_revealer_real_get_preferred_height_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum_height_out,
|
||||
gint *natural_height_out)
|
||||
{
|
||||
GtkRevealer *revealer = GTK_REVEALER (widget);
|
||||
GtkRevealerPrivate *priv = revealer->priv;
|
||||
gint minimum_height;
|
||||
gint natural_height;
|
||||
GtkRevealerTransitionType transition;
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_revealer_parent_class)->get_preferred_height_for_width (widget, width, &minimum_height, &natural_height);
|
||||
|
||||
transition = effective_transition (revealer);
|
||||
if (transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_UP ||
|
||||
transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_DOWN)
|
||||
natural_height = round (natural_height * priv->current_pos);
|
||||
|
||||
minimum_height = natural_height;
|
||||
|
||||
if (minimum_height_out)
|
||||
*minimum_height_out = minimum_height;
|
||||
if (natural_height_out)
|
||||
*natural_height_out = natural_height;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_revealer_real_get_preferred_width (GtkWidget *widget,
|
||||
gint *minimum_width_out,
|
||||
gint *natural_width_out)
|
||||
{
|
||||
GtkRevealer *revealer = GTK_REVEALER (widget);
|
||||
GtkRevealerPrivate *priv = revealer->priv;
|
||||
gint minimum_width;
|
||||
gint natural_width;
|
||||
GtkRevealerTransitionType transition;
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_revealer_parent_class)->get_preferred_width (widget, &minimum_width, &natural_width);
|
||||
|
||||
transition = effective_transition (revealer);
|
||||
if (transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_LEFT ||
|
||||
transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_RIGHT)
|
||||
natural_width = round (natural_width * priv->current_pos);
|
||||
|
||||
minimum_width = natural_width;
|
||||
|
||||
if (minimum_width_out)
|
||||
*minimum_width_out = minimum_width;
|
||||
if (natural_width_out)
|
||||
*natural_width_out = natural_width;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_revealer_real_get_preferred_width_for_height (GtkWidget *widget,
|
||||
gint height,
|
||||
gint *minimum_width_out,
|
||||
gint *natural_width_out)
|
||||
{
|
||||
GtkRevealer *revealer = GTK_REVEALER (widget);
|
||||
GtkRevealerPrivate *priv = revealer->priv;
|
||||
gint minimum_width;
|
||||
gint natural_width;
|
||||
GtkRevealerTransitionType transition;
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_revealer_parent_class)->get_preferred_width_for_height (widget, height, &minimum_width, &natural_width);
|
||||
|
||||
transition = effective_transition (revealer);
|
||||
if (transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_LEFT ||
|
||||
transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_RIGHT)
|
||||
natural_width = round (natural_width * priv->current_pos);
|
||||
|
||||
minimum_width = natural_width;
|
||||
|
||||
if (minimum_width_out)
|
||||
*minimum_width_out = minimum_width;
|
||||
if (natural_width_out)
|
||||
*natural_width_out = natural_width;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_revealer_get_transition_duration:
|
||||
* @revealer: a #GtkRevealer
|
||||
*
|
||||
* Returns the amount of time (in milliseconds) that
|
||||
* transitions will take.
|
||||
*
|
||||
* Returns: the transition duration
|
||||
*
|
||||
* Since: 3.10
|
||||
*/
|
||||
guint
|
||||
gtk_revealer_get_transition_duration (GtkRevealer *revealer)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_REVEALER (revealer), 0);
|
||||
|
||||
return revealer->priv->transition_duration;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_revealer_set_transition_duration:
|
||||
* @revealer: a #GtkRevealer
|
||||
* @duration: the new duration, in milliseconds
|
||||
*
|
||||
* Sets the duration that transitions will take.
|
||||
*
|
||||
* Since: 3.10
|
||||
*/
|
||||
void
|
||||
gtk_revealer_set_transition_duration (GtkRevealer *revealer,
|
||||
guint value)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_REVEALER (revealer));
|
||||
|
||||
revealer->priv->transition_duration = value;
|
||||
g_object_notify (G_OBJECT (revealer), "transition-duration");
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_revealer_get_transition_type:
|
||||
* @revealer: a #GtkRevealer
|
||||
*
|
||||
* Gets the type of animation that will be used
|
||||
* for transitions in @revealer.
|
||||
*
|
||||
* Return value: the current transition type of @revealer
|
||||
*
|
||||
* Since: 3.10
|
||||
*/
|
||||
GtkRevealerTransitionType
|
||||
gtk_revealer_get_transition_type (GtkRevealer *revealer)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_REVEALER (revealer), GTK_REVEALER_TRANSITION_TYPE_NONE);
|
||||
|
||||
return revealer->priv->transition_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_revealer_set_transition_type:
|
||||
* @revealer: a #GtkRevealer
|
||||
* @transition: the new transition type
|
||||
*
|
||||
* Sets the type of animation that will be used for
|
||||
* transitions in @revealer. Available types include
|
||||
* various kinds of fades and slides.
|
||||
*
|
||||
* Since: 3.10
|
||||
*/
|
||||
void
|
||||
gtk_revealer_set_transition_type (GtkRevealer *revealer,
|
||||
GtkRevealerTransitionType transition)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_REVEALER (revealer));
|
||||
|
||||
revealer->priv->transition_type = transition;
|
||||
gtk_widget_queue_resize (GTK_WIDGET (revealer));
|
||||
g_object_notify (G_OBJECT (revealer), "transition-type");
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) 2013 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program 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 program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Author: Alexander Larsson <alexl@redhat.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __GTK_REVEALER_H__
|
||||
#define __GTK_REVEALER_H__
|
||||
|
||||
#include <gtk/gtkbin.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
#define GTK_TYPE_REVEALER (gtk_revealer_get_type ())
|
||||
#define GTK_REVEALER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_REVEALER, GtkRevealer))
|
||||
#define GTK_REVEALER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_REVEALER, GtkRevealerClass))
|
||||
#define GTK_IS_REVEALER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_REVEALER))
|
||||
#define GTK_IS_REVEALER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_REVEALER))
|
||||
#define GTK_REVEALER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_REVEALER, GtkRevealerClass))
|
||||
|
||||
typedef struct _GtkRevealer GtkRevealer;
|
||||
typedef struct _GtkRevealerClass GtkRevealerClass;
|
||||
typedef struct _GtkRevealerPrivate GtkRevealerPrivate;
|
||||
|
||||
typedef enum {
|
||||
GTK_REVEALER_TRANSITION_TYPE_NONE,
|
||||
GTK_REVEALER_TRANSITION_TYPE_CROSSFADE,
|
||||
GTK_REVEALER_TRANSITION_TYPE_SLIDE_RIGHT,
|
||||
GTK_REVEALER_TRANSITION_TYPE_SLIDE_LEFT,
|
||||
GTK_REVEALER_TRANSITION_TYPE_SLIDE_UP,
|
||||
GTK_REVEALER_TRANSITION_TYPE_SLIDE_DOWN
|
||||
} GtkRevealerTransitionType;
|
||||
|
||||
struct _GtkRevealer {
|
||||
GtkBin parent_instance;
|
||||
GtkRevealerPrivate * priv;
|
||||
};
|
||||
|
||||
struct _GtkRevealerClass {
|
||||
GtkBinClass parent_class;
|
||||
};
|
||||
|
||||
GType gtk_revealer_get_type (void) G_GNUC_CONST;
|
||||
GtkWidget* gtk_revealer_new (void);
|
||||
gboolean gtk_revealer_get_reveal_child (GtkRevealer *revealer);
|
||||
void gtk_revealer_set_reveal_child (GtkRevealer *revealer,
|
||||
gboolean reveal_child);
|
||||
gboolean gtk_revealer_get_child_revealed (GtkRevealer *revealer);
|
||||
guint gtk_revealer_get_transition_duration (GtkRevealer *revealer);
|
||||
void gtk_revealer_set_transition_duration (GtkRevealer *revealer,
|
||||
guint duration);
|
||||
void gtk_revealer_set_transition_type (GtkRevealer *revealer,
|
||||
GtkRevealerTransitionType transition);
|
||||
GtkRevealerTransitionType gtk_revealer_get_transition_type (GtkRevealer *revealer);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
||||
@@ -1880,7 +1880,7 @@ gtk_scale_buildable_custom_finished (GtkBuildable *buildable,
|
||||
if (strcmp (tagname, "marks") == 0)
|
||||
{
|
||||
GSList *m;
|
||||
gchar *markup;
|
||||
const gchar *markup;
|
||||
|
||||
marks_data = (MarksSubparserData *)user_data;
|
||||
|
||||
|
||||
@@ -93,16 +93,61 @@ get_vfunc_name (GtkOrientation orientation,
|
||||
return for_size < 0 ? "get_preferred_height" : "get_preferred_height_for_width";
|
||||
}
|
||||
|
||||
static gboolean
|
||||
widget_class_has_baseline_support (GtkWidgetClass *widget_class)
|
||||
{
|
||||
GtkWidgetClass *parent_class;
|
||||
|
||||
if (widget_class->get_preferred_height_and_baseline_for_width == NULL)
|
||||
return FALSE;
|
||||
|
||||
/* This is kinda hacky, but for backwards compatibility reasons we have to handle the case
|
||||
where a class previously did not support get_preferred_height_and_baseline_for_width,
|
||||
but then gained support for it, and a subclass of it overrides the previous non-baseline
|
||||
methods. If this happens we need to call the overridden (non-baseline supporting) versions
|
||||
on the subclass, rather than the inherited but not overriddent new get_preferred_height_and_baseline_for_width.
|
||||
*/
|
||||
|
||||
/* Loop over all parent classes that inherit the same get_preferred_height_and_baseline_for_width */
|
||||
parent_class = g_type_class_peek_parent (widget_class);
|
||||
while (parent_class != NULL &&
|
||||
parent_class->get_preferred_height_and_baseline_for_width == widget_class->get_preferred_height_and_baseline_for_width)
|
||||
{
|
||||
if (parent_class->get_preferred_height != widget_class->get_preferred_height ||
|
||||
parent_class->get_preferred_height_for_width != widget_class->get_preferred_height_for_width)
|
||||
return FALSE;
|
||||
|
||||
parent_class = g_type_class_peek_parent (parent_class);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gtk_widget_has_baseline_support (GtkWidget *widget)
|
||||
{
|
||||
GtkWidgetClass *widget_class;
|
||||
|
||||
widget_class = GTK_WIDGET_GET_CLASS (widget);
|
||||
|
||||
return widget_class_has_baseline_support (widget_class);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_widget_query_size_for_orientation (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
gint for_size,
|
||||
gint *minimum_size,
|
||||
gint *natural_size)
|
||||
gint *natural_size,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
SizeRequestCache *cache;
|
||||
GtkWidgetClass *widget_class;
|
||||
gint min_size = 0;
|
||||
gint nat_size = 0;
|
||||
gint min_baseline = -1;
|
||||
gint nat_baseline = -1;
|
||||
gboolean found_in_cache;
|
||||
|
||||
if (gtk_widget_get_request_mode (widget) == GTK_SIZE_REQUEST_CONSTANT_SIZE)
|
||||
@@ -113,7 +158,11 @@ gtk_widget_query_size_for_orientation (GtkWidget *widget,
|
||||
orientation,
|
||||
for_size,
|
||||
&min_size,
|
||||
&nat_size);
|
||||
&nat_size,
|
||||
&min_baseline,
|
||||
&nat_baseline);
|
||||
|
||||
widget_class = GTK_WIDGET_GET_CLASS (widget);
|
||||
|
||||
if (!found_in_cache)
|
||||
{
|
||||
@@ -128,7 +177,7 @@ gtk_widget_query_size_for_orientation (GtkWidget *widget,
|
||||
if (for_size < 0)
|
||||
{
|
||||
push_recursion_check (widget, orientation, for_size);
|
||||
GTK_WIDGET_GET_CLASS (widget)->get_preferred_width (widget, &min_size, &nat_size);
|
||||
widget_class->get_preferred_width (widget, &min_size, &nat_size);
|
||||
pop_recursion_check (widget, orientation);
|
||||
}
|
||||
else
|
||||
@@ -142,17 +191,17 @@ gtk_widget_query_size_for_orientation (GtkWidget *widget,
|
||||
gtk_widget_get_preferred_height (widget, &minimum_height, &natural_height);
|
||||
|
||||
/* convert for_size to unadjusted height (for_size is a proposed allocation) */
|
||||
GTK_WIDGET_GET_CLASS (widget)->adjust_size_allocation (widget,
|
||||
GTK_ORIENTATION_VERTICAL,
|
||||
&minimum_height,
|
||||
&natural_height,
|
||||
&ignored_position,
|
||||
&adjusted_for_size);
|
||||
widget_class->adjust_size_allocation (widget,
|
||||
GTK_ORIENTATION_VERTICAL,
|
||||
&minimum_height,
|
||||
&natural_height,
|
||||
&ignored_position,
|
||||
&adjusted_for_size);
|
||||
|
||||
push_recursion_check (widget, orientation, for_size);
|
||||
GTK_WIDGET_GET_CLASS (widget)->get_preferred_width_for_height (widget,
|
||||
MAX (adjusted_for_size, minimum_height),
|
||||
&min_size, &nat_size);
|
||||
widget_class->get_preferred_width_for_height (widget,
|
||||
MAX (adjusted_for_size, minimum_height),
|
||||
&min_size, &nat_size);
|
||||
pop_recursion_check (widget, orientation);
|
||||
}
|
||||
}
|
||||
@@ -161,7 +210,12 @@ gtk_widget_query_size_for_orientation (GtkWidget *widget,
|
||||
if (for_size < 0)
|
||||
{
|
||||
push_recursion_check (widget, orientation, for_size);
|
||||
GTK_WIDGET_GET_CLASS (widget)->get_preferred_height (widget, &min_size, &nat_size);
|
||||
if (widget_class_has_baseline_support (widget_class))
|
||||
widget_class->get_preferred_height_and_baseline_for_width (widget, -1,
|
||||
&min_size, &nat_size,
|
||||
&min_baseline, &nat_baseline);
|
||||
else
|
||||
widget_class->get_preferred_height (widget, &min_size, &nat_size);
|
||||
pop_recursion_check (widget, orientation);
|
||||
}
|
||||
else
|
||||
@@ -175,17 +229,21 @@ gtk_widget_query_size_for_orientation (GtkWidget *widget,
|
||||
gtk_widget_get_preferred_width (widget, &minimum_width, &natural_width);
|
||||
|
||||
/* convert for_size to unadjusted width (for_size is a proposed allocation) */
|
||||
GTK_WIDGET_GET_CLASS (widget)->adjust_size_allocation (widget,
|
||||
GTK_ORIENTATION_HORIZONTAL,
|
||||
&minimum_width,
|
||||
&natural_width,
|
||||
&ignored_position,
|
||||
&adjusted_for_size);
|
||||
widget_class->adjust_size_allocation (widget,
|
||||
GTK_ORIENTATION_HORIZONTAL,
|
||||
&minimum_width,
|
||||
&natural_width,
|
||||
&ignored_position,
|
||||
&adjusted_for_size);
|
||||
|
||||
push_recursion_check (widget, orientation, for_size);
|
||||
GTK_WIDGET_GET_CLASS (widget)->get_preferred_height_for_width (widget,
|
||||
MAX (adjusted_for_size, minimum_width),
|
||||
&min_size, &nat_size);
|
||||
if (widget_class_has_baseline_support (widget_class))
|
||||
widget_class->get_preferred_height_and_baseline_for_width (widget, MAX (adjusted_for_size, minimum_width),
|
||||
&min_size, &nat_size,
|
||||
&min_baseline, &nat_baseline);
|
||||
else
|
||||
widget_class->get_preferred_height_for_width (widget, MAX (adjusted_for_size, minimum_width),
|
||||
&min_size, &nat_size);
|
||||
pop_recursion_check (widget, orientation);
|
||||
}
|
||||
}
|
||||
@@ -198,10 +256,10 @@ gtk_widget_query_size_for_orientation (GtkWidget *widget,
|
||||
|
||||
adjusted_min = min_size;
|
||||
adjusted_natural = nat_size;
|
||||
GTK_WIDGET_GET_CLASS (widget)->adjust_size_request (widget,
|
||||
orientation,
|
||||
&adjusted_min,
|
||||
&adjusted_natural);
|
||||
widget_class->adjust_size_request (widget,
|
||||
orientation,
|
||||
&adjusted_min,
|
||||
&adjusted_natural);
|
||||
|
||||
if (adjusted_min < min_size ||
|
||||
adjusted_natural < nat_size)
|
||||
@@ -229,11 +287,42 @@ gtk_widget_query_size_for_orientation (GtkWidget *widget,
|
||||
nat_size = adjusted_natural;
|
||||
}
|
||||
|
||||
if (min_baseline != -1 || nat_baseline != -1)
|
||||
{
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
g_warning ("%s %p reported a horizontal baseline",
|
||||
G_OBJECT_TYPE_NAME (widget), widget);
|
||||
min_baseline = -1;
|
||||
nat_baseline = -1;
|
||||
}
|
||||
else if (min_baseline == -1 || nat_baseline == -1)
|
||||
{
|
||||
g_warning ("%s %p reported baseline for only one of min/natural (min: %d, natural: %d)",
|
||||
G_OBJECT_TYPE_NAME (widget), widget,
|
||||
min_baseline, nat_baseline);
|
||||
min_baseline = -1;
|
||||
nat_baseline = -1;
|
||||
}
|
||||
else if (gtk_widget_get_valign_with_baseline (widget) != GTK_ALIGN_BASELINE)
|
||||
{
|
||||
/* Ignore requested baseline for non-aligned widgets */
|
||||
min_baseline = -1;
|
||||
nat_baseline = -1;
|
||||
}
|
||||
else
|
||||
widget_class->adjust_baseline_request (widget,
|
||||
&min_baseline,
|
||||
&nat_baseline);
|
||||
}
|
||||
|
||||
_gtk_size_request_cache_commit (cache,
|
||||
orientation,
|
||||
for_size,
|
||||
min_size,
|
||||
nat_size);
|
||||
nat_size,
|
||||
min_baseline,
|
||||
nat_baseline);
|
||||
}
|
||||
|
||||
if (minimum_size)
|
||||
@@ -242,15 +331,26 @@ gtk_widget_query_size_for_orientation (GtkWidget *widget,
|
||||
if (natural_size)
|
||||
*natural_size = nat_size;
|
||||
|
||||
if (minimum_baseline)
|
||||
*minimum_baseline = min_baseline;
|
||||
|
||||
if (natural_baseline)
|
||||
*natural_baseline = nat_baseline;
|
||||
|
||||
g_assert (min_size <= nat_size);
|
||||
|
||||
GTK_NOTE (SIZE_REQUEST,
|
||||
g_print ("[%p] %s\t%s: %d is minimum %d and natural: %d (hit cache: %s)\n",
|
||||
g_print ("[%p] %s\t%s: %d is minimum %d and natural: %d",
|
||||
widget, G_OBJECT_TYPE_NAME (widget),
|
||||
orientation == GTK_ORIENTATION_HORIZONTAL ?
|
||||
"width for height" : "height for width" ,
|
||||
for_size, min_size, nat_size,
|
||||
found_in_cache ? "yes" : "no"));
|
||||
for_size, min_size, nat_size);
|
||||
if (min_baseline != -1 || nat_baseline != -1)
|
||||
g_print (", baseline %d/%d",
|
||||
min_baseline, nat_baseline);
|
||||
g_print (" (hit cache: %s)\n",
|
||||
found_in_cache ? "yes" : "no")
|
||||
);
|
||||
}
|
||||
|
||||
/* This is the main function that checks for a cached size and
|
||||
@@ -263,7 +363,9 @@ _gtk_widget_compute_size_for_orientation (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
gint for_size,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
GHashTable *widgets;
|
||||
GHashTableIter iter;
|
||||
@@ -276,12 +378,17 @@ _gtk_widget_compute_size_for_orientation (GtkWidget *widget,
|
||||
*minimum = 0;
|
||||
if (natural)
|
||||
*natural = 0;
|
||||
if (minimum_baseline)
|
||||
*minimum_baseline = -1;
|
||||
if (natural_baseline)
|
||||
*natural_baseline = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (G_LIKELY (!_gtk_widget_get_sizegroups (widget)))
|
||||
{
|
||||
gtk_widget_query_size_for_orientation (widget, orientation, for_size, minimum, natural);
|
||||
gtk_widget_query_size_for_orientation (widget, orientation, for_size, minimum, natural,
|
||||
minimum_baseline, natural_baseline);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -295,7 +402,7 @@ _gtk_widget_compute_size_for_orientation (GtkWidget *widget,
|
||||
GtkWidget *tmp_widget = key;
|
||||
gint min_dimension, nat_dimension;
|
||||
|
||||
gtk_widget_query_size_for_orientation (tmp_widget, orientation, for_size, &min_dimension, &nat_dimension);
|
||||
gtk_widget_query_size_for_orientation (tmp_widget, orientation, for_size, &min_dimension, &nat_dimension, NULL, NULL);
|
||||
|
||||
min_result = MAX (min_result, min_dimension);
|
||||
nat_result = MAX (nat_result, nat_dimension);
|
||||
@@ -305,6 +412,13 @@ _gtk_widget_compute_size_for_orientation (GtkWidget *widget,
|
||||
|
||||
g_hash_table_destroy (widgets);
|
||||
|
||||
/* Baselines make no sense with sizegroups really */
|
||||
if (minimum_baseline)
|
||||
*minimum_baseline = -1;
|
||||
|
||||
if (natural_baseline)
|
||||
*natural_baseline = -1;
|
||||
|
||||
if (minimum)
|
||||
*minimum = min_result;
|
||||
|
||||
@@ -377,7 +491,8 @@ gtk_widget_get_preferred_width (GtkWidget *widget,
|
||||
GTK_ORIENTATION_HORIZONTAL,
|
||||
-1,
|
||||
minimum_width,
|
||||
natural_width);
|
||||
natural_width,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
@@ -411,7 +526,8 @@ gtk_widget_get_preferred_height (GtkWidget *widget,
|
||||
GTK_ORIENTATION_VERTICAL,
|
||||
-1,
|
||||
minimum_height,
|
||||
natural_height);
|
||||
natural_height,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
@@ -448,7 +564,8 @@ gtk_widget_get_preferred_width_for_height (GtkWidget *widget,
|
||||
GTK_ORIENTATION_HORIZONTAL,
|
||||
height,
|
||||
minimum_width,
|
||||
natural_width);
|
||||
natural_width,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -483,7 +600,122 @@ gtk_widget_get_preferred_height_for_width (GtkWidget *widget,
|
||||
GTK_ORIENTATION_VERTICAL,
|
||||
width,
|
||||
minimum_height,
|
||||
natural_height);
|
||||
natural_height,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_widget_get_preferred_height_and_baseline_for_width:
|
||||
* @widget: a #GtkWidget instance
|
||||
* @width: the width which is available for allocation, or -1 if none
|
||||
* @minimum_height: (out) (allow-none): location for storing the minimum height, or %NULL
|
||||
* @natural_height: (out) (allow-none): location for storing the natural height, or %NULL
|
||||
* @minimum_baseline: (out) (allow-none): location for storing the baseline for the minimum height, or %NULL
|
||||
* @natural_baseline: (out) (allow-none): location for storing the baseline for the natural height, or %NULL
|
||||
*
|
||||
* Retrieves a widget's minimum and natural height and the corresponding baselines if it would be given
|
||||
* the specified @width, or the default height if @width is -1. The baselines may be -1 which means
|
||||
* that no baseline is requested for this widget.
|
||||
*
|
||||
* The returned request will be modified by the
|
||||
* GtkWidgetClass::adjust_size_request and GtkWidgetClass::adjust_baseline_request virtual methods
|
||||
* and by any #GtkSizeGroup<!-- -->s that have been applied. That is, the returned request
|
||||
* is the one that should be used for layout, not necessarily the one
|
||||
* returned by the widget itself.
|
||||
*
|
||||
* Since: 3.10
|
||||
*/
|
||||
void
|
||||
gtk_widget_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum_height,
|
||||
gint *natural_height,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
g_return_if_fail (minimum_height != NULL || natural_height != NULL);
|
||||
g_return_if_fail (width >= -1);
|
||||
|
||||
_gtk_widget_compute_size_for_orientation (widget,
|
||||
GTK_ORIENTATION_VERTICAL,
|
||||
width,
|
||||
minimum_height,
|
||||
natural_height,
|
||||
minimum_baseline,
|
||||
natural_baseline);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_widget_get_preferred_size_and_baseline:
|
||||
* @widget: a #GtkWidget instance
|
||||
* @minimum_size: (out) (allow-none): location for storing the minimum size, or %NULL
|
||||
* @natural_size: (out) (allow-none): location for storing the natural size, or %NULL
|
||||
*
|
||||
* Retrieves the minimum and natural size and the corresponding baselines of a widget, taking
|
||||
* into account the widget's preference for height-for-width management. The baselines may
|
||||
* be -1 which means that no baseline is requested for this widget.
|
||||
*
|
||||
* This is used to retrieve a suitable size by container widgets which do
|
||||
* not impose any restrictions on the child placement. It can be used
|
||||
* to deduce toplevel window and menu sizes as well as child widgets in
|
||||
* free-form containers such as GtkLayout.
|
||||
*
|
||||
* <note><para>Handle with care. Note that the natural height of a height-for-width
|
||||
* widget will generally be a smaller size than the minimum height, since the required
|
||||
* height for the natural width is generally smaller than the required height for
|
||||
* the minimum width.</para></note>
|
||||
*
|
||||
* Since: 3.10
|
||||
*/
|
||||
void
|
||||
gtk_widget_get_preferred_size_and_baseline (GtkWidget *widget,
|
||||
GtkRequisition *minimum_size,
|
||||
GtkRequisition *natural_size,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
gint min_width, nat_width;
|
||||
gint min_height, nat_height;
|
||||
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
|
||||
if (gtk_widget_get_request_mode (widget) == GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
|
||||
{
|
||||
gtk_widget_get_preferred_width (widget, &min_width, &nat_width);
|
||||
|
||||
if (minimum_size)
|
||||
{
|
||||
minimum_size->width = min_width;
|
||||
gtk_widget_get_preferred_height_and_baseline_for_width (widget, min_width,
|
||||
&minimum_size->height, NULL, minimum_baseline, NULL);
|
||||
}
|
||||
|
||||
if (natural_size)
|
||||
{
|
||||
natural_size->width = nat_width;
|
||||
gtk_widget_get_preferred_height_and_baseline_for_width (widget, nat_width,
|
||||
NULL, &natural_size->height, NULL, natural_baseline);
|
||||
}
|
||||
}
|
||||
else /* GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT or CONSTANT_SIZE */
|
||||
{
|
||||
gtk_widget_get_preferred_height_and_baseline_for_width (widget, -1, &min_height, &nat_height, minimum_baseline, natural_baseline);
|
||||
|
||||
if (minimum_size)
|
||||
{
|
||||
minimum_size->height = min_height;
|
||||
gtk_widget_get_preferred_width_for_height (widget, min_height,
|
||||
&minimum_size->width, NULL);
|
||||
}
|
||||
|
||||
if (natural_size)
|
||||
{
|
||||
natural_size->height = nat_height;
|
||||
gtk_widget_get_preferred_width_for_height (widget, nat_height,
|
||||
NULL, &natural_size->width);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -505,6 +737,9 @@ gtk_widget_get_preferred_height_for_width (GtkWidget *widget,
|
||||
* height for the natural width is generally smaller than the required height for
|
||||
* the minimum width.</para></note>
|
||||
*
|
||||
* Use gtk_widget_get_preferred_size_and_baseline() if you want to support
|
||||
* baseline alignment.
|
||||
*
|
||||
* Since: 3.0
|
||||
*/
|
||||
void
|
||||
@@ -512,50 +747,10 @@ gtk_widget_get_preferred_size (GtkWidget *widget,
|
||||
GtkRequisition *minimum_size,
|
||||
GtkRequisition *natural_size)
|
||||
{
|
||||
gint min_width, nat_width;
|
||||
gint min_height, nat_height;
|
||||
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
|
||||
if (gtk_widget_get_request_mode (widget) == GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
|
||||
{
|
||||
gtk_widget_get_preferred_width (widget, &min_width, &nat_width);
|
||||
|
||||
if (minimum_size)
|
||||
{
|
||||
minimum_size->width = min_width;
|
||||
gtk_widget_get_preferred_height_for_width (widget, min_width,
|
||||
&minimum_size->height, NULL);
|
||||
}
|
||||
|
||||
if (natural_size)
|
||||
{
|
||||
natural_size->width = nat_width;
|
||||
gtk_widget_get_preferred_height_for_width (widget, nat_width,
|
||||
NULL, &natural_size->height);
|
||||
}
|
||||
}
|
||||
else /* GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT or CONSTANT_SIZE */
|
||||
{
|
||||
gtk_widget_get_preferred_height (widget, &min_height, &nat_height);
|
||||
|
||||
if (minimum_size)
|
||||
{
|
||||
minimum_size->height = min_height;
|
||||
gtk_widget_get_preferred_width_for_height (widget, min_height,
|
||||
&minimum_size->width, NULL);
|
||||
}
|
||||
|
||||
if (natural_size)
|
||||
{
|
||||
natural_size->height = nat_height;
|
||||
gtk_widget_get_preferred_width_for_height (widget, nat_height,
|
||||
NULL, &natural_size->width);
|
||||
}
|
||||
}
|
||||
gtk_widget_get_preferred_size_and_baseline (widget, minimum_size, natural_size,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
static gint
|
||||
compare_gap (gconstpointer p1,
|
||||
gconstpointer p2,
|
||||
@@ -657,3 +852,39 @@ gtk_distribute_natural_allocation (gint extra_space,
|
||||
|
||||
return extra_space;
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_widget_get_preferred_size_for_size (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
gint size,
|
||||
gint *minimum,
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
g_return_if_fail (size >= -1);
|
||||
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
if (size < 0)
|
||||
gtk_widget_get_preferred_width (widget, minimum, natural);
|
||||
else
|
||||
gtk_widget_get_preferred_width_for_height (widget, size, minimum, natural);
|
||||
|
||||
if (minimum_baseline)
|
||||
*minimum_baseline = -1;
|
||||
if (natural_baseline)
|
||||
*natural_baseline = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_widget_get_preferred_height_and_baseline_for_width (widget,
|
||||
size,
|
||||
minimum,
|
||||
natural,
|
||||
minimum_baseline,
|
||||
natural_baseline);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||