From 79c4bde2b473956bebe53c56c8d27d9dc70b5bce Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Tue, 17 Oct 2006 19:53:29 +0000 Subject: Some infrastructure for scrolling. Based on epiphany extension. --- (limited to 'lib') diff --git a/lib/python/_sugar.c b/lib/python/_sugar.c index c9ddef2..4d937e9 100644 --- a/lib/python/_sugar.c +++ b/lib/python/_sugar.c @@ -12,8 +12,9 @@ #include "sugar-key-grabber.h" #include "sugar-address-entry.h" #include "sugar-tray-manager.h" +#include "sugar-push-scroller.h" -#line 17 "_sugar.c" +#line 18 "_sugar.c" /* ---------- types from other modules ---------- */ @@ -32,8 +33,9 @@ PyTypeObject G_GNUC_INTERNAL PySugarAddressEntry_Type; PyTypeObject G_GNUC_INTERNAL PySugarBrowser_Type; PyTypeObject G_GNUC_INTERNAL PySugarKeyGrabber_Type; PyTypeObject G_GNUC_INTERNAL PySugarTrayManager_Type; +PyTypeObject G_GNUC_INTERNAL PySugarPushScroller_Type; -#line 37 "_sugar.c" +#line 39 "_sugar.c" @@ -327,6 +329,94 @@ PyTypeObject G_GNUC_INTERNAL PySugarTrayManager_Type = { +/* ----------- SugarPushScroller ----------- */ + +static PyObject * +_wrap_sugar_push_scroller_start(PyGObject *self, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = { "browser", "x", "y", NULL }; + PyGObject *browser; + int x, y; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!ii:SugarPushScroller.start", kwlist, &PySugarBrowser_Type, &browser, &x, &y)) + return NULL; + + sugar_push_scroller_start(SUGAR_PUSH_SCROLLER(self->obj), SUGAR_BROWSER(browser->obj), x, y); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +_wrap_sugar_push_scroller_stop(PyGObject *self, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = { "timestamp", NULL }; + unsigned long timestamp; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs,"k:SugarPushScroller.stop", kwlist, ×tamp)) + return NULL; + + sugar_push_scroller_stop(SUGAR_PUSH_SCROLLER(self->obj), timestamp); + + Py_INCREF(Py_None); + return Py_None; +} + +static const PyMethodDef _PySugarPushScroller_methods[] = { + { "start", (PyCFunction)_wrap_sugar_push_scroller_start, METH_VARARGS|METH_KEYWORDS, + NULL }, + { "stop", (PyCFunction)_wrap_sugar_push_scroller_stop, METH_VARARGS|METH_KEYWORDS, + NULL }, + { NULL, NULL, 0, NULL } +}; + +PyTypeObject G_GNUC_INTERNAL PySugarPushScroller_Type = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + "gecko.PushScroller", /* tp_name */ + sizeof(PyGObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)0, /* tp_dealloc */ + (printfunc)0, /* tp_print */ + (getattrfunc)0, /* tp_getattr */ + (setattrfunc)0, /* tp_setattr */ + (cmpfunc)0, /* tp_compare */ + (reprfunc)0, /* tp_repr */ + (PyNumberMethods*)0, /* tp_as_number */ + (PySequenceMethods*)0, /* tp_as_sequence */ + (PyMappingMethods*)0, /* tp_as_mapping */ + (hashfunc)0, /* tp_hash */ + (ternaryfunc)0, /* tp_call */ + (reprfunc)0, /* tp_str */ + (getattrofunc)0, /* tp_getattro */ + (setattrofunc)0, /* tp_setattro */ + (PyBufferProcs*)0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + NULL, /* Documentation string */ + (traverseproc)0, /* tp_traverse */ + (inquiry)0, /* tp_clear */ + (richcmpfunc)0, /* tp_richcompare */ + offsetof(PyGObject, weakreflist), /* tp_weaklistoffset */ + (getiterfunc)0, /* tp_iter */ + (iternextfunc)0, /* tp_iternext */ + (struct PyMethodDef*)_PySugarPushScroller_methods, /* tp_methods */ + (struct PyMemberDef*)0, /* tp_members */ + (struct PyGetSetDef*)0, /* tp_getset */ + NULL, /* tp_base */ + NULL, /* tp_dict */ + (descrgetfunc)0, /* tp_descr_get */ + (descrsetfunc)0, /* tp_descr_set */ + offsetof(PyGObject, inst_dict), /* tp_dictoffset */ + (initproc)0, /* tp_init */ + (allocfunc)0, /* tp_alloc */ + (newfunc)0, /* tp_new */ + (freefunc)0, /* tp_free */ + (inquiry)0 /* tp_is_gc */ +}; + + + /* ----------- functions ----------- */ static PyObject * @@ -419,11 +509,13 @@ py_sugar_register_classes(PyObject *d) } -#line 423 "_sugar.c" +#line 513 "_sugar.c" pygobject_register_class(d, "SugarAddressEntry", SUGAR_TYPE_ADDRESS_ENTRY, &PySugarAddressEntry_Type, Py_BuildValue("(O)", &PyGtkEntry_Type)); pygobject_register_class(d, "SugarBrowser", SUGAR_TYPE_BROWSER, &PySugarBrowser_Type, Py_BuildValue("(O)", &PyGtkMozEmbed_Type)); pygobject_register_class(d, "SugarKeyGrabber", SUGAR_TYPE_KEY_GRABBER, &PySugarKeyGrabber_Type, Py_BuildValue("(O)", &PyGObject_Type)); pyg_set_object_has_new_constructor(SUGAR_TYPE_KEY_GRABBER); pygobject_register_class(d, "SugarTrayManager", SUGAR_TYPE_TRAY_MANAGER, &PySugarTrayManager_Type, Py_BuildValue("(O)", &PyGObject_Type)); pyg_set_object_has_new_constructor(SUGAR_TYPE_TRAY_MANAGER); + pygobject_register_class(d, "SugarPushScroller", SUGAR_TYPE_PUSH_SCROLLER, &PySugarPushScroller_Type, Py_BuildValue("(O)", &PyGObject_Type)); + pyg_set_object_has_new_constructor(SUGAR_TYPE_PUSH_SCROLLER); } diff --git a/lib/python/_sugar.defs b/lib/python/_sugar.defs index 2829f2a..570d68b 100644 --- a/lib/python/_sugar.defs +++ b/lib/python/_sugar.defs @@ -28,6 +28,13 @@ (gtype-id "SUGAR_TYPE_TRAY_MANAGER") ) +(define-object PushScroller + (in-module "Sugar") + (parent "GObject") + (c-name "SugarPushScroller") + (gtype-id "SUGAR_TYPE_PUSH_SCROLLER") +) + ;; Enumerations and flags ... @@ -130,4 +137,29 @@ (return-type "GtkOrientation") ) +;; From sugar-push-scroller.h + +(define-function push_scroller_get_type + (c-name "sugar_push_scroller_get_type") + (return-type "GType") +) + +(define-method start + (of-object "SugarPushScroller") + (c-name "sugar_push_scroller_start") + (return-type "none") + (parameters + '("SugarBrowser*" "browser") + '("int" "x") + '("int" "y") + ) +) +(define-method stop + (of-object "SugarPushScroller") + (c-name "sugar_push_scroller_stop") + (return-type "none") + (parameters + '("guint32" "timestamp") + ) +) diff --git a/lib/python/_sugar.override b/lib/python/_sugar.override index b27d853..57e7c28 100644 --- a/lib/python/_sugar.override +++ b/lib/python/_sugar.override @@ -8,6 +8,7 @@ headers #include "sugar-key-grabber.h" #include "sugar-address-entry.h" #include "sugar-tray-manager.h" +#include "sugar-push-scroller.h" %% modulename gecko diff --git a/lib/src/Makefile.am b/lib/src/Makefile.am index 9ade0e3..03c3f76 100644 --- a/lib/src/Makefile.am +++ b/lib/src/Makefile.am @@ -16,6 +16,8 @@ libsugarprivate_la_SOURCES = \ sugar-address-entry.c \ sugar-key-grabber.h \ sugar-key-grabber.c \ + sugar-push-scroller.c \ + sugar-push-scroller.h \ sugar-tray-manager.c \ sugar-tray-manager.h diff --git a/lib/src/sugar-browser.cpp b/lib/src/sugar-browser.cpp index 51b4598..0032a2f 100644 --- a/lib/src/sugar-browser.cpp +++ b/lib/src/sugar-browser.cpp @@ -19,9 +19,13 @@ #include "sugar-browser.h" +#include #include #include #include +#include +#include +#include enum { PROP_0, @@ -252,3 +256,27 @@ sugar_browser_init(SugarBrowser *browser) g_signal_connect(G_OBJECT(browser), "location", G_CALLBACK(location_cb), NULL); } + +void +sugar_browser_scroll_pixels(SugarBrowser *browser, + int dx, + int dy) +{ + nsCOMPtr webBrowser; + gtk_moz_embed_get_nsIWebBrowser (GTK_MOZ_EMBED(browser), + getter_AddRefs(webBrowser)); + NS_ENSURE_TRUE (webBrowser, ); + + nsCOMPtr webBrowserFocus; + webBrowserFocus = do_QueryInterface (webBrowser); + NS_ENSURE_TRUE (webBrowserFocus, ); + + nsCOMPtr DOMWindow; + webBrowserFocus->GetFocusedWindow (getter_AddRefs(DOMWindow)); + if (!DOMWindow) { + webBrowser->GetContentDOMWindow (getter_AddRefs (DOMWindow)); + } + NS_ENSURE_TRUE (DOMWindow, ); + + DOMWindow->ScrollBy (dx, dy); +} diff --git a/lib/src/sugar-browser.h b/lib/src/sugar-browser.h index d04d729..9ea2d6c 100644 --- a/lib/src/sugar-browser.h +++ b/lib/src/sugar-browser.h @@ -55,6 +55,9 @@ struct _SugarBrowserClass { GType sugar_browser_get_type (void); void sugar_browser_startup (void); SugarBrowser *sugar_browser_create_window (SugarBrowser *browser); +void sugar_browser_scroll_pixels (SugarBrowser *browser, + int dx, + int dy); G_END_DECLS diff --git a/lib/src/sugar-push-scroller.c b/lib/src/sugar-push-scroller.c new file mode 100644 index 0000000..aaff3f6 --- /dev/null +++ b/lib/src/sugar-push-scroller.c @@ -0,0 +1,195 @@ +/* + * Copyright © 2002 Ricardo Fernádez Pascual + * Copyright © 2005 Crispin Flowerday + * Copyright © 2005 Christian Persch + * Copyright © 2005 Samuel Abels + * Copyright (C) 2006, Red Hat, Inc. + * + * This program 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, 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Id: ephy-push-scroller.c,v 1.6 2006/09/13 19:01:24 chpe Exp $ + */ + +/* this file is based on work of Daniel Erat for galeon 1 */ + +#include "sugar-push-scroller.h" + +#include +#include +#include + +#include + +#define SUGAR_PUSH_SCROLLER_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), SUGAR_TYPE_PUSH_SCROLLER, SugarPushScrollerPrivate)) + +struct _SugarPushScrollerPrivate +{ + SugarBrowser *browser; + GdkCursor *cursor; + guint start_x; + guint start_y; + guint active : 1; +}; + +G_DEFINE_TYPE(SugarPushScroller, sugar_push_scroller, G_TYPE_OBJECT) + +/* private functions */ + +static gboolean +sugar_push_scroller_motion_cb(GtkWidget *widget, + GdkEventMotion *event, + SugarPushScroller *scroller) +{ + SugarPushScrollerPrivate *priv = scroller->priv; + int x_dist, x_dist_abs, y_dist, y_dist_abs; + + if (!priv->active) { + return FALSE; + } + + /* get distance between last known cursor position and cursor */ + x_dist = priv->start_x - event->x_root; + x_dist_abs = abs(x_dist); + y_dist = priv->start_y - event->y_root; + y_dist_abs = abs(y_dist); + + /* scroll */ + sugar_browser_scroll_pixels(priv->browser, x_dist, y_dist); + + priv->start_x = event->x_root; + priv->start_y = event->y_root; + + return TRUE; +} + +/* public functions */ + +void +sugar_push_scroller_start (SugarPushScroller *scroller, + SugarBrowser *browser, + int x, + int y) +{ + SugarPushScrollerPrivate *priv = scroller->priv; + GtkWidget *widget, *window; + guint32 timestamp; + + g_return_if_fail (browser != NULL); + + if (priv->active) + return; + + if (gdk_pointer_is_grabbed ()) + return; + + priv->active = TRUE; + + /* FIXME is this good enough? */ + timestamp = gtk_get_current_event_time(); + + g_object_ref (scroller); + + priv->browser = browser; + + window = gtk_widget_get_toplevel(GTK_WIDGET(browser)); + g_object_ref (window); + + /* set positions */ + priv->start_x = x; + priv->start_y = y; + + g_signal_connect(window, "motion-notify-event", + G_CALLBACK (sugar_push_scroller_motion_cb), scroller); + + /* grab the pointer */ + widget = GTK_WIDGET(window); + gtk_grab_add(widget); + if (gdk_pointer_grab(widget->window, FALSE, + GDK_POINTER_MOTION_MASK | + GDK_BUTTON_PRESS_MASK | + GDK_BUTTON_RELEASE_MASK, + NULL, priv->cursor, timestamp) != GDK_GRAB_SUCCESS) { + sugar_push_scroller_stop(scroller, timestamp); + return; + } +} + +void +sugar_push_scroller_stop (SugarPushScroller *scroller, + guint32 timestamp) +{ + SugarPushScrollerPrivate *priv = scroller->priv; + GtkWidget *widget, *window; + + if (priv->active == FALSE) + return; + + window = gtk_widget_get_toplevel(GTK_WIDGET(priv->browser)); + + /* disconnect the signals before ungrabbing! */ + g_signal_handlers_disconnect_matched (window, + G_SIGNAL_MATCH_DATA, 0, 0, + NULL, NULL, scroller); + + /* ungrab the pointer if it's grabbed */ + if (gdk_pointer_is_grabbed()) + { + gdk_pointer_ungrab(timestamp); + } + + gdk_keyboard_ungrab(timestamp); + + widget = GTK_WIDGET(window); + gtk_grab_remove(widget); + + g_object_unref(window); + + priv->browser = NULL; + priv->active = FALSE; + + g_object_unref(scroller); +} + +/* class implementation */ + +static void +sugar_push_scroller_init (SugarPushScroller *scroller) +{ + SugarPushScrollerPrivate *priv; + priv = scroller->priv = SUGAR_PUSH_SCROLLER_GET_PRIVATE(scroller); + priv->active = FALSE; + priv->cursor = gdk_cursor_new(GDK_FLEUR); +} + +static void +sugar_push_scroller_finalize (GObject *object) +{ + SugarPushScroller *scroller = SUGAR_PUSH_SCROLLER(object); + SugarPushScrollerPrivate *priv = scroller->priv; + + gdk_cursor_unref(priv->cursor); + + G_OBJECT_CLASS(sugar_push_scroller_parent_class)->finalize(object); +} + +static void +sugar_push_scroller_class_init (SugarPushScrollerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS(klass); + + object_class->finalize = sugar_push_scroller_finalize; + + g_type_class_add_private(klass, sizeof (SugarPushScrollerPrivate)); +} diff --git a/lib/src/sugar-push-scroller.h b/lib/src/sugar-push-scroller.h new file mode 100644 index 0000000..69a2335 --- /dev/null +++ b/lib/src/sugar-push-scroller.h @@ -0,0 +1,66 @@ +/* + * Copyright © 2002 Ricardo Fernádez Pascual + * Copyright © 2005 Crispin Flowerday + * Copyright © 2005 Christian Persch + * Copyright (C) 2006, Red Hat, Inc. + * + * This program 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, 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Id: ephy-push-scroller.h,v 1.2 2006/09/13 19:01:24 chpe Exp $ + */ + +#ifndef SUGAR_PUSH_SCROLLER_H +#define SUGAR_PUSH_SCROLLER_H + +#include +#include + +#include "sugar-browser.h" + +G_BEGIN_DECLS + +#define SUGAR_TYPE_PUSH_SCROLLER (sugar_push_scroller_get_type()) +#define SUGAR_PUSH_SCROLLER(object) (G_TYPE_CHECK_INSTANCE_CAST((object), SUGAR_TYPE_PUSH_SCROLLER, SugarPushScroller)) +#define SUGAR_PUSH_SCROLLER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), SUGAR_TYPE_PUSH_SCROLLER, SugarPushScrollerClass)) +#define SUGAR_IS_PUSH_SCROLLER(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), SUGAR_TYPE_PUSH_SCROLLER)) +#define SUGAR_IS_PUSH_SCROLLER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SUGAR_TYPE_PUSH_SCROLLER)) +#define SUGAR_PUSH_SCROLLER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), SUGAR_TYPE_PUSH_SCROLLER, SugarPushScrollerClass)) + +typedef struct _SugarPushScrollerClass SugarPushScrollerClass; +typedef struct _SugarPushScroller SugarPushScroller; +typedef struct _SugarPushScrollerPrivate SugarPushScrollerPrivate; + +struct _SugarPushScrollerClass { + GObjectClass parent_class; +}; + +struct _SugarPushScroller { + GObject parent_object; + + /*< private >*/ + SugarPushScrollerPrivate *priv; +}; + +GType sugar_push_scroller_get_type (void); +void sugar_push_scroller_start (SugarPushScroller *scroller, + SugarBrowser *browser, + int x, + int y); +void sugar_push_scroller_stop (SugarPushScroller *scroller, + guint32 timestamp); + +G_END_DECLS + +#endif -- cgit v0.9.1