From: Matt Birkholz Date: Sat, 8 Jul 2017 03:30:25 +0000 (-0700) Subject: gtk: GtkScrolledView (and GtkPanedView) for 3.22.11 (Ubuntu 17.04). X-Git-Tag: mit-scheme-pucked-9.2.12~108 X-Git-Url: https://birchwood-abbey.net/git?a=commitdiff_plain;h=3d17f94c4f38a9de0e87e7386836627035ef1aaf;p=mit-scheme.git gtk: GtkScrolledView (and GtkPanedView) for 3.22.11 (Ubuntu 17.04). --- diff --git a/src/gtk/Makefile.am b/src/gtk/Makefile.am index e60ca8475..5bec07fd9 100644 --- a/src/gtk/Makefile.am +++ b/src/gtk/Makefile.am @@ -144,6 +144,7 @@ EXTRA_DIST += gtkpanedview-3.14.13.c gtkscrolledview-3.14.13.c EXTRA_DIST += gtkpanedview-3.16.7.c gtkscrolledview-3.16.7.c EXTRA_DIST += gtkpanedview-3.18.9.c gtkscrolledview-3.18.9.c EXTRA_DIST += gtkpanedview-3.20.9.c gtkscrolledview-3.20.9.c +EXTRA_DIST += gtkpanedview-3.22.11.c gtkscrolledview-3.22.11.c EXTRA_DIST += conses.png hello.scm test-gport-performance.scm EXTRA_DIST += debian diff --git a/src/gtk/configure.ac b/src/gtk/configure.ac index 0541b90d1..848a043fe 100644 --- a/src/gtk/configure.ac +++ b/src/gtk/configure.ac @@ -74,6 +74,8 @@ AC_ARG_WITH([gtk-version], if test "${with_gtk_version}" != guess; then GTK_VERSION=$with_gtk_version +elif pkg-config --exists 'gtk+-3.0 >= 3.22.11' 2>/dev/null; then + GTK_VERSION=3.22.11 elif pkg-config --exists 'gtk+-3.0 >= 3.20.9' 2>/dev/null; then GTK_VERSION=3.20.9 elif pkg-config --exists 'gtk+-3.0 >= 3.18.9' 2>/dev/null; then diff --git a/src/gtk/gtkpanedview-3.22.11.c b/src/gtk/gtkpanedview-3.22.11.c new file mode 100644 index 000000000..8714d5a01 --- /dev/null +++ b/src/gtk/gtkpanedview-3.22.11.c @@ -0,0 +1,59 @@ +/* -*-C-*- + +Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, + 2016, 2017 Matthew Birkholz + +This file is part of a Gtk plugin for MIT/GNU Scheme Pucked. + +This plugin is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +This plugin 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 +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this plugin; if not, write to the Free Software Foundation, +Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + +/* A specialized GtkPaned. See documentation of . */ + +/* The v3.20.9 of GtkPaned seems to do the right thing with + GtkScrolledViews, so this version of GtkPanedView is not actually + specialized. */ + +#include "gtkpanedview.h" + +G_DEFINE_TYPE (GtkPanedView, gtk_paned_view, + GTK_TYPE_PANED) + +static void +gtk_paned_view_class_init (GtkPanedViewClass *class) +{ +} + +static void +gtk_paned_view_init (GtkPanedView *paned_view) +{ +} + +/** + * gtk_paned_view_new: + * @orientation: GTK_ORIENTATION_VERTICAL or GTK_ORIENTATION_HORIZONTAL. + * + * Creates a new paned view. + * + * Returns: a new paned view. + */ +GtkWidget* +gtk_paned_view_new (GtkOrientation orientation) +{ + return (g_object_new (GTK_TYPE_PANED_VIEW, + "orientation", orientation, + NULL)); +} diff --git a/src/gtk/gtkscrolledview-3.22.11.c b/src/gtk/gtkscrolledview-3.22.11.c new file mode 100644 index 000000000..c0b8d7954 --- /dev/null +++ b/src/gtk/gtkscrolledview-3.22.11.c @@ -0,0 +1,361 @@ +/* -*-C-*- + +Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, + 2016, 2017 Matthew Birkholz + +This file is part of a Gtk plugin for MIT/GNU Scheme Pucked. + +This plugin is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +This plugin 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 +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this plugin; if not, write to the Free Software Foundation, +Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + +/* A specialized GtkScrolledWindow. See documentation of + . */ + +#include "gtkscrolledview.h" + +static void gtk_scrolled_window_get_preferred_width (GtkWidget *widget, + gint *minimum_size, + gint *natural_size); +static void gtk_scrolled_window_get_preferred_height (GtkWidget *widget, + gint *minimum_size, + gint *natural_size); +static void gtk_scrolled_window_get_preferred_height_for_width (GtkWidget *layout, + gint width, + gint *minimum_height, + gint *natural_height); +static void gtk_scrolled_window_get_preferred_width_for_height (GtkWidget *layout, + gint width, + gint *minimum_height, + gint *natural_height); + +G_DEFINE_TYPE (GtkScrolledView, gtk_scrolled_view, + GTK_TYPE_SCROLLED_WINDOW) + +static void +gtk_scrolled_view_class_init (GtkScrolledViewClass *class) +{ + GtkWidgetClass *widget_class = (GtkWidgetClass*) class; + + widget_class->get_preferred_width = gtk_scrolled_window_get_preferred_width; + widget_class->get_preferred_height = gtk_scrolled_window_get_preferred_height; + widget_class->get_preferred_height_for_width = gtk_scrolled_window_get_preferred_height_for_width; + widget_class->get_preferred_width_for_height = gtk_scrolled_window_get_preferred_width_for_height; +} + +static void +gtk_scrolled_view_init (GtkScrolledView *scrolled_view) +{ + g_assert (GTK_SCROLLED_WINDOW (scrolled_view) ->priv != NULL); +} + +/** + * gtk_scrolled_view_new: + * @hadjustment: (allow-none): horizontal adjustment + * @vadjustment: (allow-none): vertical adjustment + * + * Creates a new scrolling window. + * + * The two arguments are the scrolling window's adjustments; these will be + * shared with the scrollbars and the child widget to keep the bars in sync + * with the child. Usually you want to pass %NULL for the adjustments, which + * will cause the scrolling window to create them for you. + * + * Returns: a new scrolling window + */ +GtkWidget* +gtk_scrolled_view_new (GtkAdjustment *hadjustment, + GtkAdjustment *vadjustment) +{ + GtkWidget *scrolled_view; + + if (hadjustment) + g_return_val_if_fail (GTK_IS_ADJUSTMENT (hadjustment), NULL); + + if (vadjustment) + g_return_val_if_fail (GTK_IS_ADJUSTMENT (vadjustment), NULL); + + scrolled_view = g_object_new (GTK_TYPE_SCROLLED_VIEW, + "hadjustment", hadjustment, + "vadjustment", vadjustment, + NULL); + + return scrolled_view; +} + +/* The following definitions were copied unchanged from + gtkscrolledwindow.c v3.18.9 unless otherwise noted. The geometry + protocol methods in v3.20.9 now use private gadget functions, but + the v3.18.9 code is still correct, so it is used instead. This + presumably means limited CSS styling for GtkScrolledView (until the + gadget functions are no longer private). + + struct _GtkProgressTracker v3.22.11 + struct Indicator v3.22.11 + struct _GtkScrolledWindowPrivate v3.22.11 + static gint _gtk_scrolled_window_get_scrollbar_spacing () + static void gtk_scrolled_window_get_preferred_size () PATCHED + static void gtk_scrolled_window_get_preferred_width () + static void gtk_scrolled_window_get_preferred_height () + static void gtk_scrolled_window_get_preferred_height_for_width () + static void gtk_scrolled_window_get_preferred_width_for_height () +*/ + +typedef struct _GtkProgressTracker GtkProgressTracker; + +struct _GtkProgressTracker +{ + gboolean is_running; + guint64 last_frame_time; + guint64 duration; + gdouble iteration; + gdouble iteration_count; +}; + +typedef struct +{ + GtkWidget *scrollbar; + GdkWindow *window; + gboolean over; /* either mouse over, or while dragging */ + gint64 last_scroll_time; + guint conceil_timer; + + gdouble current_pos; + gdouble source_pos; + gdouble target_pos; + GtkProgressTracker tracker; + guint tick_id; + guint over_timeout_id; +} Indicator; + +typedef long GtkCssGadget; +typedef long GtkCssNode; + +struct _GtkScrolledWindowPrivate +{ + GtkWidget *hscrollbar; + GtkWidget *vscrollbar; + + GtkCssGadget *gadget; + GtkCssNode *overshoot_node[4]; + GtkCssNode *undershoot_node[4]; + + Indicator hindicator; + Indicator vindicator; + + GtkCornerType window_placement; + guint16 shadow_type; + + guint hscrollbar_policy : 2; + guint vscrollbar_policy : 2; + guint hscrollbar_visible : 1; + guint vscrollbar_visible : 1; + guint focus_out : 1; /* used by ::move-focus-out implementation */ + guint overlay_scrolling : 1; + guint use_indicators : 1; + guint auto_added_viewport : 1; + guint propagate_natural_width : 1; + guint propagate_natural_height : 1; + + gint min_content_width; + gint min_content_height; + gint max_content_width; + gint max_content_height; + + guint scroll_events_overshoot_id; + + /* Kinetic scrolling */ + GtkGesture *long_press_gesture; + GtkGesture *swipe_gesture; + + GArray *scroll_history; + GdkDevice *scroll_device; + GdkWindow *scroll_window; + GdkCursor *scroll_cursor; + + /* These two gestures are mutually exclusive */ + GtkGesture *drag_gesture; + GtkGesture *pan_gesture; + + gdouble drag_start_x; + gdouble drag_start_y; + + GdkDevice *drag_device; + guint kinetic_scrolling : 1; + guint capture_button_press : 1; + guint in_drag : 1; + + guint deceleration_id; + + gdouble x_velocity; + gdouble y_velocity; + + gdouble unclamped_hadj_value; + gdouble unclamped_vadj_value; +}; + +static gint +_gtk_scrolled_window_get_scrollbar_spacing (GtkScrolledWindow *scrolled_window) +{ + GtkScrolledWindowClass *class; + + g_return_val_if_fail (GTK_IS_SCROLLED_WINDOW (scrolled_window), 0); + + class = GTK_SCROLLED_WINDOW_GET_CLASS (scrolled_window); + + if (class->scrollbar_spacing >= 0) + return class->scrollbar_spacing; + else + { + gint scrollbar_spacing; + + gtk_widget_style_get (GTK_WIDGET (scrolled_window), + "scrollbar-spacing", &scrollbar_spacing, + NULL); + + return scrollbar_spacing; + } +} + +static void +gtk_scrolled_window_get_preferred_size (GtkWidget *widget, + GtkOrientation orientation, + gint *minimum_size, + gint *natural_size) +{ + GtkScrolledWindow *scrolled_window = GTK_SCROLLED_WINDOW (widget); + GtkScrolledWindowPrivate *priv = scrolled_window->priv; + GtkBin *bin = GTK_BIN (scrolled_window); + GtkWidget *child; + gint min_size, nat_size; + + child = gtk_bin_get_child (bin); + if (child && gtk_widget_get_visible (child)) + { + if (orientation == GTK_ORIENTATION_HORIZONTAL) + { + gtk_widget_get_preferred_width (child, &min_size, &nat_size); + if (priv->min_content_width >= 0) + min_size = MAX (min_size, priv->min_content_width); + } + else /* GTK_ORIENTATION_VERTICAL */ + { + gtk_widget_get_preferred_height (child, &min_size, &nat_size); + if (priv->min_content_height >= 0) + min_size = MAX (min_size, priv->min_content_height); + } + } + + if (!priv->use_indicators) + { + if (orientation == GTK_ORIENTATION_HORIZONTAL) + { + if (priv->vscrollbar_policy != GTK_POLICY_NEVER) + { + gint min_width, nat_width; + gint scrollbar_spacing = _gtk_scrolled_window_get_scrollbar_spacing (scrolled_window); + gtk_widget_get_preferred_width (priv->vscrollbar, &min_width, &nat_width); + min_size += MAX (0, scrollbar_spacing + min_width); + nat_size += MAX (0, scrollbar_spacing + nat_width); + } + if (priv->hscrollbar_policy != GTK_POLICY_NEVER) + { + gint min_width, nat_width; + gtk_widget_get_preferred_width (priv->hscrollbar, &min_width, &nat_width); + min_size = MAX (min_size, min_width); + nat_size = MAX (nat_size, nat_width); + } + } + else /* orientation == GTK_ORIENTATION_VERTICAL */ + { + if (priv->hscrollbar_policy != GTK_POLICY_NEVER) + { + gint min_height, nat_height; + gint scrollbar_spacing = _gtk_scrolled_window_get_scrollbar_spacing (scrolled_window); + gtk_widget_get_preferred_height (priv->hscrollbar, &min_height, &nat_height); + min_size += MAX (0, scrollbar_spacing + min_height); + nat_size += MAX (0, scrollbar_spacing + nat_height); + } + if (priv->vscrollbar_policy != GTK_POLICY_NEVER) + { + gint min_height, nat_height; + gtk_widget_get_preferred_height (priv->vscrollbar, &min_height, &nat_height); + min_size = MAX (min_size, min_height); + nat_size = MAX (nat_size, nat_height); + } + } + } + + if (priv->shadow_type != GTK_SHADOW_NONE) + { + GtkStyleContext *context; + GtkStateFlags state; + GtkBorder padding, border; + + context = gtk_widget_get_style_context (GTK_WIDGET (widget)); + state = gtk_style_context_get_state (context); + + gtk_style_context_get_padding (context, state, &padding); + gtk_style_context_get_border (context, state, &border); + + if (orientation == GTK_ORIENTATION_HORIZONTAL) + { + min_size += padding.left + padding.right + border.left + border.right; + nat_size += padding.left + padding.right + border.left + border.right; + } + else + { + min_size += padding.top + padding.bottom + border.top + border.bottom; + nat_size += padding.top + padding.bottom + border.top + border.bottom; + } + } + + *minimum_size = min_size; + *natural_size = nat_size; +} + +static void +gtk_scrolled_window_get_preferred_width (GtkWidget *widget, + gint *minimum_size, + gint *natural_size) +{ + gtk_scrolled_window_get_preferred_size (widget, GTK_ORIENTATION_HORIZONTAL, minimum_size, natural_size); +} + +static void +gtk_scrolled_window_get_preferred_height (GtkWidget *widget, + gint *minimum_size, + gint *natural_size) +{ + gtk_scrolled_window_get_preferred_size (widget, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size); +} + +static void +gtk_scrolled_window_get_preferred_height_for_width (GtkWidget *widget, + gint width, + gint *minimum_height, + gint *natural_height) +{ + GTK_WIDGET_GET_CLASS (widget)->get_preferred_height (widget, minimum_height, natural_height); +} + +static void +gtk_scrolled_window_get_preferred_width_for_height (GtkWidget *widget, + gint height, + gint *minimum_width, + gint *natural_width) +{ + GTK_WIDGET_GET_CLASS (widget)->get_preferred_width (widget, minimum_width, natural_width); +}