[gnome-control-center/wip/garnacho/wayland-tablet: 4/31] wacom: Add CcDrawingArea



commit 59b3705339d760aeaf6290c57ed1d547a16b29fb
Author: Carlos Garnacho <carlosg gnome org>
Date:   Mon Jun 6 13:09:37 2016 +0200

    wacom: Add CcDrawingArea
    
    This is a testing drawing widget that can be used to the a feeling
    of changes to stylus settings.

 panels/wacom/Makefile.am       |    2 +
 panels/wacom/cc-drawing-area.c |  214 ++++++++++++++++++++++++++++++++++++++++
 panels/wacom/cc-drawing-area.h |   37 +++++++
 3 files changed, 253 insertions(+), 0 deletions(-)
---
diff --git a/panels/wacom/Makefile.am b/panels/wacom/Makefile.am
index 21b41d6..b1f3146 100644
--- a/panels/wacom/Makefile.am
+++ b/panels/wacom/Makefile.am
@@ -19,6 +19,8 @@ BUILT_SOURCES =                       \
 
 libwacom_properties_la_SOURCES =       \
        $(BUILT_SOURCES)                \
+       cc-drawing-area.c               \
+       cc-drawing-area.h               \
        cc-wacom-panel.c                \
        cc-wacom-panel.h                \
        gsd-wacom-key-shortcut-button.c \
diff --git a/panels/wacom/cc-drawing-area.c b/panels/wacom/cc-drawing-area.c
new file mode 100644
index 0000000..6c63597
--- /dev/null
+++ b/panels/wacom/cc-drawing-area.c
@@ -0,0 +1,214 @@
+/*
+ * Copyright © 2016 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 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Carlos Garnacho <carlosg gnome org>
+ */
+
+#include "config.h"
+#include <cairo/cairo.h>
+#include "cc-drawing-area.h"
+
+typedef struct _CcDrawingArea CcDrawingArea;
+
+struct _CcDrawingArea {
+       GtkEventBox parent;
+       GdkDevice *current_device;
+       cairo_surface_t *surface;
+       cairo_t *cr;
+};
+
+G_DEFINE_TYPE (CcDrawingArea, cc_drawing_area, GTK_TYPE_EVENT_BOX)
+
+static void
+ensure_drawing_surface (CcDrawingArea *area,
+                       gint           width,
+                       gint           height)
+{
+       if (!area->surface ||
+           cairo_image_surface_get_width (area->surface) != width ||
+           cairo_image_surface_get_height (area->surface) != height) {
+               cairo_surface_t *surface;
+
+               surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+                                                     width, height);
+               if (area->surface) {
+                       cairo_t *cr;
+
+                       cr = cairo_create (surface);
+                       cairo_set_source_surface (cr, area->surface, 0, 0);
+                       cairo_paint (cr);
+
+                       cairo_surface_destroy (area->surface);
+                       cairo_destroy (area->cr);
+                       cairo_destroy (cr);
+               }
+
+               area->surface = surface;
+               area->cr = cairo_create (surface);
+       }
+}
+
+static void
+cc_drawing_area_size_allocate (GtkWidget     *widget,
+                              GtkAllocation *allocation)
+{
+       CcDrawingArea *area = CC_DRAWING_AREA (widget);
+
+       ensure_drawing_surface (area, allocation->width, allocation->height);
+
+       GTK_WIDGET_CLASS (cc_drawing_area_parent_class)->size_allocate (widget,
+                                                                       allocation);
+}
+
+static void
+cc_drawing_area_map (GtkWidget *widget)
+{
+       GtkAllocation allocation;
+
+       GTK_WIDGET_CLASS (cc_drawing_area_parent_class)->map (widget);
+
+       gtk_widget_get_allocation (widget, &allocation);
+       ensure_drawing_surface (CC_DRAWING_AREA (widget),
+                               allocation.width, allocation.height);
+}
+
+static void
+cc_drawing_area_unmap (GtkWidget *widget)
+{
+       CcDrawingArea *area = CC_DRAWING_AREA (widget);
+
+       if (area->cr) {
+               cairo_destroy (area->cr);
+               area->cr = NULL;
+       }
+
+       if (area->surface) {
+               cairo_surface_destroy (area->surface);
+               area->surface = NULL;
+       }
+
+       GTK_WIDGET_CLASS (cc_drawing_area_parent_class)->unmap (widget);
+}
+
+static gboolean
+cc_drawing_area_draw (GtkWidget *widget,
+                     cairo_t   *cr)
+{
+       CcDrawingArea *area = CC_DRAWING_AREA (widget);
+       GtkAllocation allocation;
+
+       GTK_WIDGET_CLASS (cc_drawing_area_parent_class)->draw (widget, cr);
+
+       gtk_widget_get_allocation (widget, &allocation);
+       cairo_set_source_rgb (cr, 1, 1, 1);
+       cairo_paint (cr);
+
+       cairo_set_source_surface (cr, area->surface, 0, 0);
+       cairo_paint (cr);
+
+       cairo_set_source_rgb (cr, 0.6, 0.6, 0.6);
+       cairo_rectangle (cr, 0, 0, allocation.width, allocation.height);
+       cairo_stroke (cr);
+
+       return FALSE;
+}
+
+static gboolean
+cc_drawing_area_event (GtkWidget *widget,
+                      GdkEvent  *event)
+{
+       CcDrawingArea *area = CC_DRAWING_AREA (widget);
+       GdkInputSource source;
+       GdkDeviceTool *tool;
+       GdkDevice *device;
+
+       device = gdk_event_get_source_device (event);
+
+       if (!device)
+               return GDK_EVENT_PROPAGATE;
+
+       source = gdk_device_get_source (device);
+       tool = gdk_event_get_device_tool (event);
+
+       if (source != GDK_SOURCE_PEN && source != GDK_SOURCE_ERASER)
+               return GDK_EVENT_PROPAGATE;
+
+       if (area->current_device && area->current_device != device)
+               return GDK_EVENT_PROPAGATE;
+
+       if (event->type == GDK_BUTTON_PRESS &&
+           event->button.button == 1 && !area->current_device) {
+               area->current_device = device;
+       } else if (event->type == GDK_BUTTON_RELEASE &&
+                  event->button.button == 1 && area->current_device) {
+               cairo_new_path (area->cr);
+               area->current_device = NULL;
+       } else if (event->type == GDK_MOTION_NOTIFY &&
+                  event->motion.state & GDK_BUTTON1_MASK) {
+               gdouble x, y, pressure;
+
+               gdk_event_get_coords (event, &x, &y);
+               gdk_event_get_axis (event, GDK_AXIS_PRESSURE, &pressure);
+
+               if (gdk_device_tool_get_tool_type (tool) == GDK_DEVICE_TOOL_TYPE_ERASER) {
+                       cairo_set_line_width (area->cr, 10 * pressure);
+                       cairo_set_operator (area->cr, CAIRO_OPERATOR_DEST_OUT);
+               } else {
+                       cairo_set_line_width (area->cr, 4 * pressure);
+                       cairo_set_operator (area->cr, CAIRO_OPERATOR_SATURATE);
+               }
+
+               cairo_set_source_rgba (area->cr, 0, 0, 0, pressure);
+               cairo_line_to (area->cr, x, y);
+               cairo_stroke (area->cr);
+
+               cairo_move_to (area->cr, x, y);
+
+               gtk_widget_queue_draw (widget);
+
+               return GDK_EVENT_STOP;
+       }
+
+       return GDK_EVENT_PROPAGATE;
+}
+
+static void
+cc_drawing_area_class_init (CcDrawingAreaClass *klass)
+{
+       GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+       widget_class->size_allocate = cc_drawing_area_size_allocate;
+       widget_class->draw = cc_drawing_area_draw;
+       widget_class->event = cc_drawing_area_event;
+       widget_class->map = cc_drawing_area_map;
+       widget_class->unmap = cc_drawing_area_unmap;
+}
+
+static void
+cc_drawing_area_init (CcDrawingArea *area)
+{
+       gtk_event_box_set_above_child (GTK_EVENT_BOX (area), TRUE);
+       gtk_widget_add_events (GTK_WIDGET (area),
+                              GDK_BUTTON_PRESS_MASK |
+                              GDK_BUTTON_RELEASE_MASK |
+                              GDK_POINTER_MOTION_MASK);
+}
+
+GtkWidget *
+cc_drawing_area_new (void)
+{
+       return g_object_new (CC_TYPE_DRAWING_AREA, NULL);
+}
diff --git a/panels/wacom/cc-drawing-area.h b/panels/wacom/cc-drawing-area.h
new file mode 100644
index 0000000..a994f48
--- /dev/null
+++ b/panels/wacom/cc-drawing-area.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright © 2016 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 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Carlos Garnacho <carlosg gnome org>
+ */
+
+#ifndef _CC_DRAWING_AREA_H
+#define _CC_DRAWING_AREA_H
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define CC_TYPE_DRAWING_AREA cc_drawing_area_get_type()
+
+G_DECLARE_FINAL_TYPE (CcDrawingArea, cc_drawing_area, CC, DRAWING_AREA, GtkEventBox)
+
+GType      cc_drawing_area_get_type (void) G_GNUC_CONST;
+
+GtkWidget *cc_drawing_area_new      (void);
+
+G_END_DECLS
+
+#endif /* _CC_DRAWING_AREA_H */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]