[gpointing-device-settings] show mouse event while dry-run mode.
- From: Hiroyuki Ikezoe <hiikezoe src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gpointing-device-settings] show mouse event while dry-run mode.
- Date: Sun, 21 Mar 2010 11:42:19 +0000 (UTC)
commit 6e0a11a49ef4c6507a6681c5dce9e4c3e3bca23c
Author: Hiroyuki Ikezoe <poincare ikezoe net>
Date: Sun Mar 21 20:41:19 2010 +0900
show mouse event while dry-run mode.
src/Makefile.am | 2 +
src/gpds-event-feedback.c | 587 +++++++++++++++++++++++++++++++++++++++++++++
src/gpds-event-feedback.h | 55 +++++
src/gpds-main-window.c | 118 +++++++---
4 files changed, 730 insertions(+), 32 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 5cf4e5c..718c14c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -19,6 +19,8 @@ libgpds_la_SOURCES = \
gpds-grayed-desktop.h \
gpds-main-window.c \
gpds-main-window.h \
+ gpds-event-feedback.c \
+ gpds-event-feedback.h \
gpds-ui.c \
gpds-xinput-ui.c \
gpds-gconf.c \
diff --git a/src/gpds-event-feedback.c b/src/gpds-event-feedback.c
new file mode 100644
index 0000000..26e2f83
--- /dev/null
+++ b/src/gpds-event-feedback.c
@@ -0,0 +1,587 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2010 Hiroyuki Ikezoe <poincare ikezoe net>
+ *
+ * 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 3 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 program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#include <math.h>
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+#include "gpds-main-window.h"
+#include "gpds-utils.h"
+#include "gpds-ui.h"
+#include "gpds-xinput-pointer-info.h"
+#include "gpds-ui.h"
+#include "gpds-utils.h"
+#include "gpds-grayed-desktop.h"
+#include "gpds-event-feedback.h"
+
+
+enum
+{
+ PROP_0,
+ PROP_PARENT
+};
+
+typedef struct _GpdsEventFeedbackPriv GpdsEventFeedbackPriv;
+struct _GpdsEventFeedbackPriv
+{
+ GtkWidget *parent;
+ GtkImage *image;
+ GdkPixbufAnimation *buttons[5];
+ GdkPixbufAnimation *scrollings[4];
+ guint scroll_timeout_id;
+ gboolean is_scrolling;
+ GdkScrollDirection scroll_direction;
+ gboolean is_finished_scrolling;
+};
+
+#define GPDS_EVENT_FEEDBACK_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), GPDS_TYPE_EVENT_FEEDBACK, GpdsEventFeedbackPriv))
+
+G_DEFINE_TYPE(GpdsEventFeedback, gpds_event_feedback, GTK_TYPE_WINDOW)
+
+static GObject *constructor (GType type,
+ guint n_props,
+ GObjectConstructParam
+ *props);
+static void dispose (GObject *object);
+static void set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void realize (GtkWidget *widget);
+
+static void
+gpds_event_feedback_class_init (GpdsEventFeedbackClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
+
+ gobject_class->constructor = constructor;
+ gobject_class->dispose = dispose;
+ gobject_class->set_property = set_property;
+ gobject_class->get_property = get_property;
+
+ widget_class->realize = realize;
+
+ g_object_class_install_property
+ (gobject_class,
+ PROP_PARENT,
+ g_param_spec_object("parent",
+ "Parent Window",
+ "The parent window",
+ GTK_TYPE_WIDGET,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ g_type_class_add_private(gobject_class, sizeof(GpdsEventFeedbackPriv));
+}
+
+static void
+set_animation (GpdsEventFeedback *feedback, GdkPixbufAnimation *animation)
+{
+ GpdsEventFeedbackPriv *priv = GPDS_EVENT_FEEDBACK_GET_PRIVATE(feedback);
+ GdkPixbuf *pixbuf;
+ GdkBitmap *mask = NULL;
+ GdkWindow *window;
+
+ gtk_image_set_from_animation(GTK_IMAGE(priv->image), animation);
+
+ window = gtk_widget_get_window(GTK_WIDGET(feedback));
+ if (!window)
+ return;
+
+ pixbuf = gdk_pixbuf_animation_get_static_image(animation);
+ gdk_pixbuf_render_pixmap_and_mask(pixbuf, NULL, &mask, 1);
+ gdk_window_shape_combine_mask(window, mask, 0, 0);
+ gdk_window_clear(window);
+ g_object_unref(mask);
+}
+
+static void
+realize (GtkWidget *widget)
+{
+ GpdsEventFeedbackPriv *priv = GPDS_EVENT_FEEDBACK_GET_PRIVATE(widget);
+ GdkWindow *window;
+ GdkPixbuf *pixbuf;
+ GdkPixbufAnimation *animation;
+ GdkBitmap *mask = NULL;
+
+ GTK_WIDGET_CLASS(gpds_event_feedback_parent_class)->realize(widget);
+ window = gtk_widget_get_window(widget);
+
+ animation = gtk_image_get_animation(priv->image);
+ pixbuf = gdk_pixbuf_animation_get_static_image(animation);
+ gdk_pixbuf_render_pixmap_and_mask(pixbuf, NULL, &mask, 1);
+ gdk_window_shape_combine_mask(window, mask, 0, 0);
+ g_object_unref(mask);
+}
+
+static gboolean
+cb_button_press (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
+{
+ GpdsEventFeedbackPriv *priv = GPDS_EVENT_FEEDBACK_GET_PRIVATE(user_data);
+ set_animation(GPDS_EVENT_FEEDBACK(user_data), priv->buttons[event->button - 1]);
+ gtk_widget_show(GTK_WIDGET(user_data));
+ return FALSE;
+}
+
+static gboolean
+cb_button_release (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
+{
+ gtk_widget_hide(GTK_WIDGET(user_data));
+ return FALSE;
+}
+
+static gboolean
+cb_motion_notify (GtkWidget *widget, GdkEventMotion *event, gpointer user_data)
+{
+ GtkRequisition size;
+
+ gtk_widget_size_request(GTK_WIDGET(user_data), &size);
+ gtk_window_move(GTK_WINDOW(user_data),
+ event->x_root - size.width / 2,
+ event->y_root - size.height / 2);
+ return FALSE;
+}
+
+static gboolean
+finish_scrolling (gpointer data)
+{
+ GpdsEventFeedbackPriv *priv = GPDS_EVENT_FEEDBACK_GET_PRIVATE(data);
+
+ if (priv->is_finished_scrolling) {
+ gtk_widget_hide(GTK_WIDGET(data));
+ priv->is_scrolling = FALSE;
+ priv->scroll_direction = -1;
+ priv->scroll_timeout_id = 0;
+ return FALSE;
+ }
+
+ priv->is_finished_scrolling = TRUE;
+
+ return TRUE;
+}
+
+static gboolean
+cb_scroll (GtkWidget *widget, GdkEventScroll *event, gpointer user_data)
+{
+ GpdsEventFeedbackPriv *priv = GPDS_EVENT_FEEDBACK_GET_PRIVATE(user_data);
+ GtkRequisition size;
+
+ priv->is_finished_scrolling = FALSE;
+ if (priv->is_scrolling && priv->scroll_direction == event->direction)
+ return FALSE;
+
+ priv->is_scrolling = TRUE;
+
+ if (priv->scroll_direction != event->direction) {
+ set_animation(GPDS_EVENT_FEEDBACK(user_data), priv->scrollings[event->direction]);
+ gtk_widget_size_request(GTK_WIDGET(user_data), &size);
+ gtk_window_move(GTK_WINDOW(user_data),
+ event->x_root - size.width / 2,
+ event->y_root - size.height / 2);
+ gtk_widget_show(GTK_WIDGET(user_data));
+ if (priv->scroll_timeout_id == 0)
+ priv->scroll_timeout_id = g_timeout_add(200, finish_scrolling, user_data);
+ }
+ priv->scroll_direction = event->direction;
+
+ return FALSE;
+}
+
+static GObject *
+constructor (GType type, guint n_props, GObjectConstructParam *props)
+{
+ GObject *object;
+ GObjectClass *klass;
+ GpdsEventFeedbackPriv *priv;
+
+ klass = G_OBJECT_CLASS(gpds_event_feedback_parent_class);
+ object = klass->constructor(type, n_props, props);
+
+ priv = GPDS_EVENT_FEEDBACK_GET_PRIVATE(object);
+ gtk_window_set_transient_for(GTK_WINDOW(object), GTK_WINDOW(priv->parent));
+ g_signal_connect(priv->parent, "button-press-event",
+ G_CALLBACK(cb_button_press), object);
+ g_signal_connect(priv->parent, "button-release-event",
+ G_CALLBACK(cb_button_release), object);
+ g_signal_connect(priv->parent, "motion-notify-event",
+ G_CALLBACK(cb_motion_notify), object);
+ g_signal_connect(priv->parent, "scroll-event",
+ G_CALLBACK(cb_scroll), object);
+
+ return object;
+}
+
+#define IMAGE_SIZE 64
+
+static GdkPixbuf *
+cairo_surface_to_pixbuf (cairo_surface_t *surface)
+{
+ gint width, height;
+ gint x, y;
+ int n_channels;
+ guchar *src;
+ guchar *dest;
+ GdkPixbuf *pixbuf;
+
+ width = cairo_image_surface_get_width(surface);
+ height = cairo_image_surface_get_height(surface);
+
+ pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB,
+ TRUE,
+ 8,
+ width, height);
+ n_channels = gdk_pixbuf_get_n_channels(pixbuf);
+
+ src = cairo_image_surface_get_data(surface);
+ dest = gdk_pixbuf_get_pixels(pixbuf);
+
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < width; x++) {
+ guchar alpha;
+ guchar red, green, blue;
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+ alpha = src[3];
+ red = src[2];
+ green = src[1];
+ blue = src[0];
+#else
+ alpha = src[0];
+ red = src[3];
+ green = src[1];
+ blue = src[2];
+#endif
+ if (alpha == 0) {
+ dest[0] = 0;
+ dest[1] = 0;
+ dest[2] = 0;
+ } else {
+ dest[0] = (red * 0xff / alpha) & 0xff;
+ dest[1] = (green * 0xff / alpha) & 0xff;
+ dest[2] = (blue * 0xff / alpha) & 0xff;
+ }
+ dest[3] = alpha;
+
+ src += n_channels;
+ dest += n_channels;
+ }
+ }
+
+ return pixbuf;
+}
+
+#define N_ANIMATION_FRAMES 8
+
+static GdkPixbuf *
+create_number_image (guint8 number, guint frame)
+{
+ cairo_t *cr;
+ cairo_surface_t *surface;
+ cairo_text_extents_t extents;
+ cairo_pattern_t *pattern;
+ GdkPixbuf *pixbuf;
+ gdouble start;
+ gchar *text;
+
+ surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
+ IMAGE_SIZE, IMAGE_SIZE);
+
+ cr = cairo_create(surface);
+ cairo_save(cr);
+
+ cairo_rectangle(cr, 0., 0., IMAGE_SIZE, IMAGE_SIZE);
+ cairo_set_source_rgba(cr, 0., 0., 0., 0);
+ cairo_fill(cr);
+
+ cairo_set_font_size(cr, IMAGE_SIZE);
+ cairo_select_font_face(cr, "serif",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_BOLD);
+
+ text = g_strdup_printf("%d", number);
+ cairo_text_extents(cr, text, &extents);
+ cairo_move_to(cr,
+ (IMAGE_SIZE - extents.width) / 2,
+ IMAGE_SIZE - (IMAGE_SIZE - extents.height) / 2);
+ cairo_text_path(cr, text);
+ g_free(text);
+
+ start = cos(G_PI * frame / N_ANIMATION_FRAMES) * (IMAGE_SIZE / 4);
+ pattern = cairo_pattern_create_radial(IMAGE_SIZE / 2,
+ IMAGE_SIZE / 2,
+ start,
+ IMAGE_SIZE / 2,
+ IMAGE_SIZE / 2,
+ start + IMAGE_SIZE / 4);
+ cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REFLECT);
+
+ cairo_pattern_add_color_stop_rgba(pattern, 0.,
+ 1., 0., 0.,
+ 1.);
+ cairo_pattern_add_color_stop_rgba(pattern, 1.,
+ 0., 0., 1.,
+ 1.);
+
+ cairo_set_source(cr, pattern);
+ cairo_fill_preserve(cr);
+ cairo_pattern_destroy(pattern);
+
+ cairo_set_source_rgba(cr, 1., 1., 1., 1);
+ cairo_set_line_width(cr, 2);
+ cairo_stroke(cr);
+ cairo_restore(cr);
+ cairo_destroy(cr);
+
+ pixbuf = cairo_surface_to_pixbuf(surface);
+ cairo_surface_destroy(surface);
+
+ return pixbuf;
+}
+
+static GdkPixbuf *
+create_up_arrow_image (guint frame)
+{
+ cairo_t *cr;
+ cairo_surface_t *surface;
+ cairo_pattern_t *pattern;
+ GdkPixbuf *pixbuf;
+ gdouble start;
+
+ surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
+ IMAGE_SIZE, IMAGE_SIZE);
+
+
+ cr = cairo_create(surface);
+ cairo_save(cr);
+
+ cairo_rectangle(cr, 0., 0., IMAGE_SIZE, IMAGE_SIZE);
+ cairo_set_source_rgba(cr, 0., 0., 0., 0);
+ cairo_fill(cr);
+
+ cairo_move_to(cr, IMAGE_SIZE / 4, IMAGE_SIZE);
+ cairo_line_to(cr, IMAGE_SIZE / 4, IMAGE_SIZE / 2);
+ cairo_line_to(cr, 0, IMAGE_SIZE / 2);
+ cairo_line_to(cr, IMAGE_SIZE / 2, 0);
+ cairo_line_to(cr, IMAGE_SIZE, IMAGE_SIZE / 2);
+ cairo_line_to(cr, IMAGE_SIZE / 4 * 3, IMAGE_SIZE / 2);
+ cairo_line_to(cr, IMAGE_SIZE / 4 * 3, IMAGE_SIZE);
+ cairo_close_path(cr);
+
+ start = cos(G_PI * frame / N_ANIMATION_FRAMES) * (IMAGE_SIZE / 4);
+ pattern = cairo_pattern_create_linear(0., start,
+ 0., start + (IMAGE_SIZE / 4));
+ cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REFLECT);
+ cairo_pattern_add_color_stop_rgba(pattern, 0.,
+ 0., 0., 1.,
+ 0.);
+ cairo_pattern_add_color_stop_rgba(pattern, 1.,
+ 0., 0., 1.,
+ 1.);
+
+ cairo_set_source(cr, pattern);
+ cairo_fill_preserve(cr);
+ cairo_pattern_destroy(pattern);
+
+ cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND);
+ cairo_set_source_rgba(cr, 1., 1., 1., 1.);
+ cairo_set_line_width(cr, 4);
+ cairo_stroke(cr);
+ cairo_restore(cr);
+ cairo_destroy(cr);
+
+ pixbuf = cairo_surface_to_pixbuf(surface);
+ cairo_surface_destroy(surface);
+
+ return pixbuf;
+}
+
+static GdkPixbufAnimation *
+create_button_images (guint button_number)
+{
+ GdkPixbufSimpleAnim*images;
+ gint i;
+
+ images = gdk_pixbuf_simple_anim_new(IMAGE_SIZE, IMAGE_SIZE,
+ N_ANIMATION_FRAMES / 2);
+ gdk_pixbuf_simple_anim_set_loop(images, TRUE);
+
+ for (i = 0; i < N_ANIMATION_FRAMES; i++) {
+ GdkPixbuf *pixbuf;
+ pixbuf = create_number_image(button_number, i);
+ gdk_pixbuf_simple_anim_add_frame(images, pixbuf);
+ g_object_unref(pixbuf);
+ }
+
+ return GDK_PIXBUF_ANIMATION(images);
+}
+
+static GdkPixbufAnimation *
+create_arrow_images (GdkScrollDirection direction)
+{
+ GdkPixbufSimpleAnim*images;
+ gint i;
+
+ images = gdk_pixbuf_simple_anim_new(IMAGE_SIZE, IMAGE_SIZE,
+ N_ANIMATION_FRAMES / 2);
+ gdk_pixbuf_simple_anim_set_loop(images, TRUE);
+
+ for (i = 0; i < N_ANIMATION_FRAMES; i++) {
+ GdkPixbuf *pixbuf;
+ GdkPixbuf *rotate;
+ GdkPixbufRotation angle;
+
+ pixbuf = create_up_arrow_image(i);
+ switch (direction) {
+ case GDK_SCROLL_RIGHT:
+ angle = GDK_PIXBUF_ROTATE_CLOCKWISE;
+ break;
+ case GDK_SCROLL_LEFT:
+ angle = GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE;
+ break;
+ case GDK_SCROLL_DOWN:
+ angle = GDK_PIXBUF_ROTATE_UPSIDEDOWN;
+ break;
+ case GDK_SCROLL_UP:
+ default:
+ angle = GDK_PIXBUF_ROTATE_NONE;
+ break;
+ }
+
+ rotate = gdk_pixbuf_rotate_simple(pixbuf, angle);
+ gdk_pixbuf_simple_anim_add_frame(images, rotate);
+ g_object_unref(pixbuf);
+ g_object_unref(rotate);
+ }
+
+ return GDK_PIXBUF_ANIMATION(images);
+}
+
+static void
+gpds_event_feedback_init (GpdsEventFeedback *feedback)
+{
+ GpdsEventFeedbackPriv *priv = GPDS_EVENT_FEEDBACK_GET_PRIVATE(feedback);
+ gint i;
+
+ priv->parent = NULL;
+ priv->is_scrolling = FALSE;
+ priv->scroll_direction = -1;
+ priv->is_finished_scrolling = FALSE;
+ priv->scroll_timeout_id = 0;
+
+ for (i = 0; i < 5; i++)
+ priv->buttons[i] = create_button_images(i + 1);
+
+ for (i = 0; i < 4; i++)
+ priv->scrollings[i] = create_arrow_images(i);
+
+ priv->image = GTK_IMAGE(gtk_image_new());
+ gtk_container_add(GTK_CONTAINER(feedback), GTK_WIDGET(priv->image));
+ gtk_widget_show(GTK_WIDGET(priv->image));
+}
+
+static void
+dispose (GObject *object)
+{
+ GpdsEventFeedbackPriv *priv = GPDS_EVENT_FEEDBACK_GET_PRIVATE(object);
+ gint i;
+
+ if (priv->parent) {
+ g_object_unref(priv->parent);
+ priv->parent = NULL;
+ }
+
+ if (priv->scroll_timeout_id) {
+ g_source_remove(priv->scroll_timeout_id);
+ priv->scroll_timeout_id = 0;
+ }
+
+ for (i = 0; i < 5; i++) {
+ if (priv->buttons[i]) {
+ g_object_unref(priv->buttons[i]);
+ priv->buttons[i] = NULL;
+ }
+ }
+
+ for (i = 0; i < 4; i++) {
+ if (priv->scrollings[i]) {
+ g_object_unref(priv->scrollings[i]);
+ priv->scrollings[i] = NULL;
+ }
+ }
+
+ if (G_OBJECT_CLASS(gpds_event_feedback_parent_class)->dispose)
+ G_OBJECT_CLASS(gpds_event_feedback_parent_class)->dispose(object);
+}
+
+static void
+set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GpdsEventFeedbackPriv *priv = GPDS_EVENT_FEEDBACK_GET_PRIVATE(object);
+
+ switch (prop_id) {
+ case PROP_PARENT:
+ priv->parent = g_value_dup_object(value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GpdsEventFeedbackPriv *priv = GPDS_EVENT_FEEDBACK_GET_PRIVATE(object);
+
+ switch (prop_id) {
+ case PROP_PARENT:
+ g_value_set_object(value, priv->parent);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+
+GtkWidget *
+gpds_event_feedback_new (GtkWindow *parent)
+{
+ return GTK_WIDGET(g_object_new(GPDS_TYPE_EVENT_FEEDBACK,
+ "type", GTK_WINDOW_POPUP,
+ "type-hint", GDK_WINDOW_TYPE_HINT_NOTIFICATION,
+ "destroy-with-parent", TRUE,
+ "parent", parent,
+ NULL));
+}
+
+/*
+vi:ts=4:nowrap:ai:expandtab:sw=4
+*/
diff --git a/src/gpds-event-feedback.h b/src/gpds-event-feedback.h
new file mode 100644
index 0000000..fbeb7d7
--- /dev/null
+++ b/src/gpds-event-feedback.h
@@ -0,0 +1,55 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2010 Hiroyuki Ikezoe <poincare ikezoe net>
+ *
+ * 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 3 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 program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef __GPDS_EVENT_FEEDBACK_H__
+#define __GPDS_EVENT_FEEDBACK_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GPDS_TYPE_EVENT_FEEDBACK (gpds_event_feedback_get_type ())
+#define GPDS_EVENT_FEEDBACK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GPDS_TYPE_EVENT_FEEDBACK, GpdsEventFeedback))
+#define GPDS_EVENT_FEEDBACK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GPDS_TYPE_EVENT_FEEDBACK, GpdsEventFeedbackClass))
+#define GPDS_IS_EVENT_FEEDBACK(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GPDS_TYPE_EVENT_FEEDBACK))
+#define GPDS_IS_EVENT_FEEDBACK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GPDS_TYPE_EVENT_FEEDBACK))
+#define GPDS_EVENT_FEEDBACK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GPDS_TYPE_EVENT_FEEDBACK, GpdsEventFeedbackClass))
+
+typedef struct _GpdsEventFeedback GpdsEventFeedback;
+typedef struct _GpdsEventFeedbackClass GpdsEventFeedbackClass;
+
+struct _GpdsEventFeedback
+{
+ GtkWindow parent;
+};
+
+struct _GpdsEventFeedbackClass
+{
+ GtkWindowClass parent_class;
+};
+
+GType gpds_event_feedback_get_type (void) G_GNUC_CONST;
+GtkWidget *gpds_event_feedback_new (GtkWindow *parent);
+
+G_END_DECLS
+
+#endif /* __GPDS_EVENT_FEEDBACK_H__ */
+/*
+vi:ts=4:nowrap:ai:expandtab:sw=4
+*/
diff --git a/src/gpds-main-window.c b/src/gpds-main-window.c
index dea7331..05fc5bb 100644
--- a/src/gpds-main-window.c
+++ b/src/gpds-main-window.c
@@ -30,6 +30,7 @@
#include "gpds-ui.h"
#include "gpds-utils.h"
#include "gpds-grayed-desktop.h"
+#include "gpds-event-feedback.h"
enum {
DEVICE_NAME_COLUMN,
@@ -44,6 +45,7 @@ struct _GpdsMainWindowPriv
GList *uis;
GtkWidget *background;
GtkWidget *dry_run_button;
+ GtkWidget *feedback;
GtkIconView *icon_view;
GdkColor *original_text_color;
GdkColor *original_base_color;
@@ -242,6 +244,27 @@ cb_selection_changed (GtkIconView *icon_view, gpointer data)
gtk_tree_path_free(path);
}
+static gboolean
+cb_button_event (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
+{
+ gtk_widget_event(GTK_WIDGET(user_data), (GdkEvent*)event);
+ return FALSE;
+}
+
+static gboolean
+cb_motion_notify (GtkWidget *widget, GdkEventMotion *event, gpointer user_data)
+{
+ gtk_widget_event(GTK_WIDGET(user_data), (GdkEvent*)event);
+ return FALSE;
+}
+
+static gboolean
+cb_scroll (GtkWidget *widget, GdkEventScroll *event, gpointer user_data)
+{
+ gtk_widget_event(GTK_WIDGET(user_data), (GdkEvent*)event);
+ return FALSE;
+}
+
static void
gpds_main_window_init (GpdsMainWindow *window)
{
@@ -257,6 +280,7 @@ gpds_main_window_init (GpdsMainWindow *window)
priv->background = NULL;
priv->original_text_color = NULL;
priv->original_base_color = NULL;
+ priv->feedback = gpds_event_feedback_new(GTK_WINDOW(window));
device_store = gtk_list_store_new(N_COLUMNS,
G_TYPE_STRING,
@@ -334,38 +358,6 @@ heartbeat (GtkWidget *widget)
}
static gboolean
-button_press (GtkWidget *widget, GdkEventButton *event)
-{
- heartbeat(widget);
-
- return FALSE;
-}
-
-static gboolean
-button_release (GtkWidget *widget, GdkEventButton *event)
-{
- heartbeat(widget);
-
- return FALSE;
-}
-
-static gboolean
-motion_notify (GtkWidget *widget, GdkEventMotion *event)
-{
- heartbeat(widget);
-
- return FALSE;
-}
-
-static gboolean
-scroll (GtkWidget *widget, GdkEventScroll *event)
-{
- heartbeat(widget);
-
- return FALSE;
-}
-
-static gboolean
restore_original_pixbuf (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
{
GpdsMainWindowPriv *priv = GPDS_MAIN_WINDOW_GET_PRIVATE(data);
@@ -404,6 +396,51 @@ get_current_ui (GpdsMainWindow *window)
return GPDS_UI(g_list_nth_data(priv->uis, index));
}
+static gboolean
+button_press (GtkWidget *widget, GdkEventButton *event)
+{
+ heartbeat(widget);
+
+ return FALSE;
+}
+
+static gboolean
+button_release (GtkWidget *widget, GdkEventButton *event)
+{
+ heartbeat(widget);
+
+ return FALSE;
+}
+
+static gboolean
+motion_notify (GtkWidget *widget, GdkEventMotion *event)
+{
+ heartbeat(widget);
+
+ return FALSE;
+}
+
+static gboolean
+scroll (GtkWidget *widget, GdkEventScroll *event)
+{
+ heartbeat(widget);
+
+ return FALSE;
+}
+
+static void
+disconnect_icon_view_signals (GpdsMainWindow *window)
+{
+ GpdsMainWindowPriv *priv = GPDS_MAIN_WINDOW_GET_PRIVATE(window);
+
+ g_signal_handlers_disconnect_by_func(priv->icon_view,
+ G_CALLBACK(cb_button_event), window);
+ g_signal_handlers_disconnect_by_func(priv->icon_view,
+ G_CALLBACK(cb_motion_notify), window);
+ g_signal_handlers_disconnect_by_func(priv->icon_view,
+ G_CALLBACK(cb_scroll), window);
+}
+
static void
finish_dry_run (GpdsMainWindow *window)
{
@@ -422,6 +459,7 @@ finish_dry_run (GpdsMainWindow *window)
gpds_ui_finish_dry_run(ui, NULL);
+ disconnect_icon_view_signals(window);
gdk_pointer_ungrab(GDK_CURRENT_TIME);
if (priv->background) {
gtk_widget_destroy(priv->background);
@@ -502,6 +540,21 @@ set_grayscaled_pixbuf (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter
}
static void
+connect_icon_view_signals (GpdsMainWindow *window)
+{
+ GpdsMainWindowPriv *priv = GPDS_MAIN_WINDOW_GET_PRIVATE(window);
+
+ g_signal_connect(priv->icon_view, "button-press-event",
+ G_CALLBACK(cb_button_event), window);
+ g_signal_connect(priv->icon_view, "button-release-event",
+ G_CALLBACK(cb_button_event), window);
+ g_signal_connect(priv->icon_view, "motion-notify-event",
+ G_CALLBACK(cb_motion_notify), window);
+ g_signal_connect(priv->icon_view, "scroll-event",
+ G_CALLBACK(cb_scroll), window);
+}
+
+static void
start_dry_run (GpdsMainWindow *window)
{
GpdsMainWindowPriv *priv = GPDS_MAIN_WINDOW_GET_PRIVATE(window);
@@ -539,6 +592,7 @@ start_dry_run (GpdsMainWindow *window)
gtk_widget_modify_base(GTK_WIDGET(priv->icon_view),
GTK_STATE_NORMAL, &style->base[GTK_STATE_INSENSITIVE]);
gtk_widget_queue_draw(GTK_WIDGET(priv->icon_view));
+ connect_icon_view_signals(window);
grab_pointer(window);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]