[dia/zbrown/test-build: 2/6] canvas: move core parts of canvas to a new DiaCanvas type
- From: Zander Brown <zbrown src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [dia/zbrown/test-build: 2/6] canvas: move core parts of canvas to a new DiaCanvas type
- Date: Fri, 24 Sep 2021 18:56:49 +0000 (UTC)
commit eac8ee8df138a2532b3723a528d60266aa4fc968
Author: Zander Brown <zbrown gnome org>
Date: Thu Sep 23 22:07:08 2021 +0100
canvas: move core parts of canvas to a new DiaCanvas type
Override the vfuncs directly instead of connecting to signals
Add a gtk3 stub
app/dia-canvas.c | 327 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
app/dia-canvas.h | 35 ++++++
app/interface.c | 177 +----------------------------
app/interface.h | 17 ++-
app/meson.build | 2 +
lib/dia-autoptr.h | 1 +
6 files changed, 383 insertions(+), 176 deletions(-)
---
diff --git a/app/dia-canvas.c b/app/dia-canvas.c
new file mode 100644
index 000000000..306d0b403
--- /dev/null
+++ b/app/dia-canvas.c
@@ -0,0 +1,327 @@
+/* Dia -- an diagram creation/manipulation program
+ * Copyright (C) 1998 Alexander Larsson
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "config.h"
+
+#include <glib/gi18n-lib.h>
+#include <gtk/gtk.h>
+
+#include "dia-canvas.h"
+#include "disp_callbacks.h"
+#include "toolbox.h"
+#include "diainteractiverenderer.h"
+#include "interface.h"
+#include "object.h"
+
+struct _DiaCanvas {
+ GtkDrawingArea parent;
+
+ DDisplay *display;
+};
+
+G_DEFINE_TYPE (DiaCanvas, dia_canvas, GTK_TYPE_DRAWING_AREA)
+
+
+enum {
+ PROP_0,
+ PROP_DISPLAY,
+ LAST_PROP
+};
+static GParamSpec *pspecs[LAST_PROP] = { NULL, };
+
+
+static void
+dia_canvas_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ DiaCanvas *self = DIA_CANVAS (object);
+
+ switch (property_id) {
+ case PROP_DISPLAY:
+ self->display = g_value_get_pointer (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+
+static void
+dia_canvas_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ DiaCanvas *self = DIA_CANVAS (object);
+
+ switch (property_id) {
+ case PROP_DISPLAY:
+ g_value_set_pointer (value, self->display);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+
+/*!
+ * Called when the widget's window "size, position or stacking"
+ * changes. Needs GDK_STRUCTURE_MASK set.
+ */
+static gboolean
+dia_canvas_configure_event (GtkWidget *widget, GdkEventConfigure *cevent)
+{
+ DiaCanvas *self = DIA_CANVAS (widget);
+ gboolean new_size = FALSE;
+ int width, height;
+ DiaRenderer *renderer;
+
+ g_return_val_if_fail (self->display, FALSE);
+ g_return_val_if_fail (widget == self->display->canvas, FALSE);
+
+ renderer = self->display->renderer;
+
+ if (renderer) {
+ width = dia_interactive_renderer_get_width_pixels (DIA_INTERACTIVE_RENDERER (renderer));
+ height = dia_interactive_renderer_get_height_pixels (DIA_INTERACTIVE_RENDERER (renderer));
+ } else {
+ /* We can continue even without a renderer here because
+ * ddisplay_resize_canvas () does the setup for us.
+ */
+ width = height = 0;
+ }
+
+ /* Only do this when size is really changing */
+ if (width != cevent->width || height != cevent->height) {
+ g_debug ("%s: Canvas size change...", G_STRLOC);
+ ddisplay_resize_canvas (self->display, cevent->width, cevent->height);
+ ddisplay_update_scrollbars (self->display);
+ /* on resize stop further propagation - does not help */
+ new_size = TRUE;
+ }
+
+ /* If the UI is not integrated, resizing should set the resized
+ * window as active. With integrated UI, there is only one window.
+ */
+ if (is_integrated_ui () == 0) {
+ display_set_active (self->display);
+ }
+
+ /* continue propagation with FALSE */
+ return new_size;
+}
+
+
+static gboolean
+dia_canvas_draw (GtkWidget *widget, cairo_t *ctx)
+{
+ DiaCanvas *self = DIA_CANVAS (widget);
+ GSList *l;
+ DiaRectangle *r, totrect;
+ GtkAllocation alloc;
+ DiaRenderer *renderer;
+
+ g_return_val_if_fail (self->display, FALSE);
+ g_return_val_if_fail (self->display->renderer != NULL, FALSE);
+
+ renderer = self->display->renderer;
+
+ /* Only update if update_areas exist */
+ l = self->display->update_areas;
+ if (l != NULL) {
+ totrect = *(DiaRectangle *) l->data;
+
+ dia_interactive_renderer_clip_region_clear (DIA_INTERACTIVE_RENDERER (renderer));
+
+ while ( l!= NULL) {
+ r = (DiaRectangle *) l->data;
+
+ rectangle_union (&totrect, r);
+ dia_interactive_renderer_clip_region_add_rect (DIA_INTERACTIVE_RENDERER (renderer), r);
+
+ l = g_slist_next (l);
+ }
+ /* Free update_areas list: */
+ g_slist_free_full (self->display->update_areas, g_free);
+ self->display->update_areas = NULL;
+
+ totrect.left -= 0.1;
+ totrect.right += 0.1;
+ totrect.top -= 0.1;
+ totrect.bottom += 0.1;
+
+ ddisplay_render_pixmap (self->display, &totrect);
+ }
+
+ gtk_widget_get_allocation (widget, &alloc);
+
+ dia_interactive_renderer_paint (DIA_INTERACTIVE_RENDERER (renderer),
+ ctx,
+ alloc.width,
+ alloc.height);
+
+ return FALSE;
+}
+
+
+#if !GTK_CHECK_VERSION (3, 0, 0)
+static gboolean
+dia_canvas_expose_event (GtkWidget *widget, GdkEventExpose *event)
+{
+ cairo_t *ctx;
+ gboolean res;
+
+ ctx = gdk_cairo_create (GDK_DRAWABLE (gtk_widget_get_window (widget)));
+
+ res = dia_canvas_draw (widget, ctx);
+
+ cairo_destroy (ctx);
+
+ return res;
+}
+#endif
+
+
+static gboolean
+dia_canvas_event (GtkWidget *widget, GdkEvent *event)
+{
+ DiaCanvas *self = DIA_CANVAS (widget);
+
+ return ddisplay_canvas_events (widget, event, self->display);
+}
+
+
+static gboolean
+dia_canvas_drag_drop (GtkWidget *widget,
+ GdkDragContext *context,
+ int x,
+ int y,
+ guint time)
+{
+ if (gtk_drag_get_source_widget (context) != NULL) {
+ /* we only accept drops from the same instance of the application,
+ * as the drag data is a pointer in our address space */
+ return TRUE;
+ }
+
+ gtk_drag_finish (context, FALSE, FALSE, time);
+
+ return FALSE;
+}
+
+
+static void
+dia_canvas_drag_data_received (GtkWidget *widget,
+ GdkDragContext *context,
+ int x,
+ int y,
+ GtkSelectionData *data,
+ guint info,
+ guint time)
+{
+ DiaCanvas *self = DIA_CANVAS (widget);
+
+ if (gtk_selection_data_get_format (data) == 8 &&
+ gtk_selection_data_get_length (data) == sizeof (ToolButtonData *) &&
+ gtk_drag_get_source_widget(context) != NULL) {
+ ToolButtonData *tooldata = *(ToolButtonData **) gtk_selection_data_get_data (data);
+
+ ddisplay_drop_object (self->display,
+ x,
+ y,
+ object_get_type ((char *) tooldata->extra_data),
+ tooldata->user_data);
+
+ gtk_drag_finish (context, TRUE, FALSE, time);
+ } else {
+ dia_dnd_file_drag_data_received (widget,
+ context,
+ x,
+ y,
+ data,
+ info,
+ time,
+ self->display);
+ }
+
+ /* ensure the right window has the focus for text editing */
+ gtk_window_present (GTK_WINDOW (self->display->shell));
+}
+
+
+static void
+dia_canvas_class_init (DiaCanvasClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->set_property = dia_canvas_set_property;
+ object_class->get_property = dia_canvas_get_property;
+
+ widget_class->configure_event = dia_canvas_configure_event;
+#if GTK_CHECK_VERSION (3, 0, 0)
+ widget_class->draw = dia_canvas_draw;
+#else
+ widget_class->expose_event = dia_canvas_expose_event;
+#endif
+ widget_class->event = dia_canvas_event;
+ widget_class->drag_drop = dia_canvas_drag_drop;
+ widget_class->drag_data_received = dia_canvas_drag_data_received;
+
+ pspecs[PROP_DISPLAY] =
+ g_param_spec_pointer ("display",
+ "Display",
+ "The DDisplay",
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
+
+ g_object_class_install_properties (object_class, LAST_PROP, pspecs);
+}
+
+
+static void
+dia_canvas_init (DiaCanvas *self)
+{
+ gtk_widget_set_events (GTK_WIDGET (self),
+ GDK_EXPOSURE_MASK |
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK |
+ GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
+ GDK_STRUCTURE_MASK | GDK_ENTER_NOTIFY_MASK |
+ GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK);
+
+ gtk_widget_set_can_focus (GTK_WIDGET (self), TRUE);
+
+}
+
+
+GtkWidget *
+dia_canvas_new (DDisplay *ddisp)
+{
+ GtkWidget *self = g_object_new (DIA_TYPE_CANVAS,
+ "display", ddisp,
+ NULL);
+
+ g_object_set_data (G_OBJECT (self), "user_data", (gpointer) ddisp);
+
+ return self;
+}
diff --git a/app/dia-canvas.h b/app/dia-canvas.h
new file mode 100644
index 000000000..30c216927
--- /dev/null
+++ b/app/dia-canvas.h
@@ -0,0 +1,35 @@
+/* Dia -- an diagram creation/manipulation program
+ * Copyright (C) 1998 Alexander Larsson
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#pragma once
+
+#include <gtk/gtk.h>
+
+#include "dia-autoptr.h"
+#include "display.h"
+
+G_BEGIN_DECLS
+
+#define DIA_TYPE_CANVAS dia_canvas_get_type ()
+G_DECLARE_FINAL_TYPE (DiaCanvas, dia_canvas, DIA, CANVAS, GtkDrawingArea)
+
+GtkWidget *dia_canvas_new (DDisplay *ddisp);
+
+G_END_DECLS
diff --git a/app/interface.c b/app/interface.c
index 2dcdd2554..79eab1831 100644
--- a/app/interface.c
+++ b/app/interface.c
@@ -30,6 +30,7 @@
#include <stdio.h>
#include <string.h>
+#include "dia-canvas.h"
#include "diagram.h"
#include "object.h"
#include "layer-editor/layer_dialog.h"
@@ -80,7 +81,7 @@ static gboolean _ddisplay_vruler_motion_notify (GtkWidget *widget,
DDisplay *ddisp);
-static void
+void
dia_dnd_file_drag_data_received (GtkWidget *widget,
GdkDragContext *context,
int x,
@@ -335,51 +336,6 @@ create_zoom_widget(DDisplay *ddisp) {
}
-static gboolean
-display_drop_callback (GtkWidget *widget,
- GdkDragContext *context,
- int x,
- int y,
- guint time)
-{
- if (gtk_drag_get_source_widget(context) != NULL) {
- /* we only accept drops from the same instance of the application,
- * as the drag data is a pointer in our address space */
- return TRUE;
- }
- gtk_drag_finish (context, FALSE, FALSE, time);
- return FALSE;
-}
-
-
-static void
-display_data_received_callback (GtkWidget *widget,
- GdkDragContext *context,
- int x,
- int y,
- GtkSelectionData *data,
- guint info,
- guint time,
- DDisplay *ddisp)
-{
- if (gtk_selection_data_get_format(data) == 8 &&
- gtk_selection_data_get_length(data) == sizeof(ToolButtonData *) &&
- gtk_drag_get_source_widget(context) != NULL) {
- ToolButtonData *tooldata = *(ToolButtonData **)gtk_selection_data_get_data(data);
- /* g_message("Tool drop %s at (%d, %d)", (gchar *)tooldata->extra_data, x, y);*/
- ddisplay_drop_object(ddisp, x, y,
- object_get_type((gchar *)tooldata->extra_data),
- tooldata->user_data);
-
- gtk_drag_finish (context, TRUE, FALSE, time);
- } else {
- dia_dnd_file_drag_data_received (widget, context, x, y, data, info, time, ddisp);
- }
- /* ensure the right window has the focus for text editing */
- gtk_window_present(GTK_WINDOW(ddisp->shell));
-}
-
-
/**
* close_notebook_page_callback:
* @button: The notebook close button.
@@ -414,131 +370,6 @@ notebook_switch_page (GtkNotebook *notebook,
gtk_widget_grab_focus (ddisp->canvas);
}
-/*!
- * Called when the widget's window "size, position or stacking"
- * changes. Needs GDK_STRUCTURE_MASK set.
- */
-static gboolean
-canvas_configure_event (GtkWidget *widget,
- GdkEventConfigure *cevent,
- DDisplay *ddisp)
-{
- gboolean new_size = FALSE;
- int width, height;
-
- g_return_val_if_fail (widget == ddisp->canvas, FALSE);
-
- if (ddisp->renderer) {
- width = dia_interactive_renderer_get_width_pixels (DIA_INTERACTIVE_RENDERER (ddisp->renderer));
- height = dia_interactive_renderer_get_height_pixels (DIA_INTERACTIVE_RENDERER (ddisp->renderer));
- } else {
- /* We can continue even without a renderer here because
- * ddisplay_resize_canvas () does the setup for us.
- */
- width = height = 0;
- }
-
- /* Only do this when size is really changing */
- if (width != cevent->width || height != cevent->height) {
- g_debug ("%s: Canvas size change...", G_STRLOC);
- ddisplay_resize_canvas (ddisp, cevent->width, cevent->height);
- ddisplay_update_scrollbars (ddisp);
- /* on resize stop further propagation - does not help */
- new_size = TRUE;
- }
-
- /* If the UI is not integrated, resizing should set the resized
- * window as active. With integrated UI, there is only one window.
- */
- if (is_integrated_ui () == 0) {
- display_set_active (ddisp);
- }
-
- /* continue propagation with FALSE */
- return new_size;
-}
-
-static gboolean
-canvas_expose_event (GtkWidget *widget,
- GdkEventExpose *event,
- DDisplay *ddisp)
-{
- GSList *l;
- DiaRectangle *r, totrect;
- GtkAllocation alloc;
- cairo_t *ctx;
-
- ctx = gdk_cairo_create (gtk_widget_get_window (widget));
-
- g_return_val_if_fail (ddisp->renderer != NULL, FALSE);
-
- /* Only update if update_areas exist */
- l = ddisp->update_areas;
- if (l != NULL) {
- totrect = *(DiaRectangle *) l->data;
-
- dia_interactive_renderer_clip_region_clear (DIA_INTERACTIVE_RENDERER (ddisp->renderer));
-
- while ( l!= NULL) {
- r = (DiaRectangle *) l->data;
-
- rectangle_union (&totrect, r);
- dia_interactive_renderer_clip_region_add_rect (DIA_INTERACTIVE_RENDERER (ddisp->renderer), r);
-
- l = g_slist_next (l);
- }
- /* Free update_areas list: */
- g_slist_free_full (ddisp->update_areas, g_free);
- ddisp->update_areas = NULL;
-
- totrect.left -= 0.1;
- totrect.right += 0.1;
- totrect.top -= 0.1;
- totrect.bottom += 0.1;
-
- ddisplay_render_pixmap (ddisp, &totrect);
- }
-
- gtk_widget_get_allocation (widget, &alloc);
-
- dia_interactive_renderer_paint (DIA_INTERACTIVE_RENDERER (ddisp->renderer),
- ctx,
- alloc.width,
- alloc.height);
-
- return FALSE;
-}
-
-static GtkWidget *
-create_canvas (DDisplay *ddisp)
-{
- GtkWidget *canvas = gtk_drawing_area_new();
-
- gtk_widget_set_can_focus (canvas, TRUE);
-
- gtk_widget_set_events (canvas,
- GDK_EXPOSURE_MASK |
- GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK |
- GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
- GDK_STRUCTURE_MASK | GDK_ENTER_NOTIFY_MASK |
- GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK);
- g_signal_connect (G_OBJECT (canvas), "configure-event",
- G_CALLBACK (canvas_configure_event), ddisp);
- g_signal_connect (G_OBJECT (canvas), "expose-event",
- G_CALLBACK (canvas_expose_event), ddisp);
- gtk_widget_set_can_focus (canvas, TRUE);
- g_signal_connect (G_OBJECT (canvas), "event",
- G_CALLBACK (ddisplay_canvas_events), ddisp);
-
- canvas_setup_drag_dest (canvas);
- g_signal_connect (G_OBJECT (canvas), "drag_drop",
- G_CALLBACK (display_drop_callback), NULL);
- g_signal_connect (G_OBJECT (canvas), "drag_data_received",
- G_CALLBACK (display_data_received_callback), ddisp);
- g_object_set_data (G_OBJECT (canvas), "user_data", (gpointer) ddisp);
-
- return canvas;
-}
/* Shared helper functions for both UI cases
*/
@@ -740,7 +571,7 @@ use_integrated_ui_for_display_shell (DDisplay *ddisp, char *title)
_ddisplay_setup_scrollbars (ddisp, table, width, height);
_ddisplay_setup_navigation (ddisp, table, TRUE);
- ddisp->canvas = create_canvas (ddisp);
+ ddisp->canvas = dia_canvas_new (ddisp);
/* place all remaining widgets (no 'origin' anymore, since navigation is top-left */
gtk_table_attach (GTK_TABLE (table), ddisp->canvas, 1, 2, 1, 2,
@@ -871,7 +702,7 @@ create_display_shell (DDisplay *ddisp,
_ddisplay_setup_scrollbars (ddisp, table, width, height);
_ddisplay_setup_navigation (ddisp, table, FALSE);
- ddisp->canvas = create_canvas (ddisp);
+ ddisp->canvas = dia_canvas_new (ddisp);
/* pack all remaining widgets */
gtk_table_attach (GTK_TABLE (table), ddisp->origin, 0, 1, 0, 1,
diff --git a/app/interface.h b/app/interface.h
index 9396efc85..1d6593607 100644
--- a/app/interface.h
+++ b/app/interface.h
@@ -15,13 +15,15 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
-#ifndef INTERFACE_H
-#define INTERFACE_H
+
+#pragma once
#include "display.h"
#include "app_procs.h"
+G_BEGIN_DECLS
+
/* Integrated UI Constants */
#define DIA_MAIN_WINDOW "dia-main-window"
#define DIA_MAIN_NOTEBOOK "dia-main-notebook"
@@ -59,4 +61,13 @@ void close_notebook_page_callback (GtkButton *button, gpointer user_data);
double parse_zoom (const char *zoom);
-#endif /* INTERFACE_H */
+void dia_dnd_file_drag_data_received (GtkWidget *widget,
+ GdkDragContext *context,
+ int x,
+ int y,
+ GtkSelectionData *data,
+ guint info,
+ guint time,
+ DDisplay *ddisp);
+
+G_END_DECLS
diff --git a/app/meson.build b/app/meson.build
index 694bc6425..2b09b964d 100644
--- a/app/meson.build
+++ b/app/meson.build
@@ -11,6 +11,8 @@ dia_sources = [
'dia-builder.c',
'dia-builder.h',
+ 'dia-canvas.c',
+ 'dia-canvas.h',
'layer-editor/dia-layer-list.c',
'layer-editor/dia-layer-list.h',
diff --git a/lib/dia-autoptr.h b/lib/dia-autoptr.h
index 5508030c5..d47c0306f 100644
--- a/lib/dia-autoptr.h
+++ b/lib/dia-autoptr.h
@@ -32,6 +32,7 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (GtkSpinButton, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GtkComboBox, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GtkHBox, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GtkTreeView, g_object_unref)
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (GtkDrawingArea, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GtkCellRenderer, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GtkCellRendererText, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GtkBin, g_object_unref)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]