diff options
Diffstat (limited to 'src/widget.c')
-rw-r--r-- | src/widget.c | 503 |
1 files changed, 0 insertions, 503 deletions
diff --git a/src/widget.c b/src/widget.c deleted file mode 100644 index b08715b..0000000 --- a/src/widget.c +++ /dev/null @@ -1,503 +0,0 @@ -/* This file is part of Ganv. - * Copyright 2007-2016 David Robillard <http://drobilla.net> - * - * Ganv 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 3 of the License, or any later version. - * - * Ganv 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 details. - * - * You should have received a copy of the GNU General Public License along - * with Ganv. If not, see <http://www.gnu.org/licenses/>. - */ - -/* Based on GnomeCanvasWidget, by Federico Mena <federico@nuclecu.unam.mx> - * Copyright 1997-2000 Free Software Foundation - */ - -#include <math.h> - -#include <gtk/gtksignal.h> - -#include "ganv/canvas.h" -#include "ganv/widget.h" - -#include "./gettext.h" -#include "./ganv-private.h" - -G_DEFINE_TYPE_WITH_CODE(GanvWidget, ganv_widget, GANV_TYPE_ITEM, - G_ADD_PRIVATE(GanvWidget)) - -static GanvItemClass* parent_class; - -enum { - PROP_0, - PROP_WIDGET, - PROP_X, - PROP_Y, - PROP_WIDTH, - PROP_HEIGHT, - PROP_ANCHOR, - PROP_SIZE_PIXELS -}; - -static void -ganv_widget_init(GanvWidget* witem) -{ - GanvWidgetPrivate* impl = ganv_widget_get_instance_private(witem); - - witem->impl = impl; - witem->impl->x = 0.0; - witem->impl->y = 0.0; - witem->impl->width = 0.0; - witem->impl->height = 0.0; - witem->impl->anchor = GTK_ANCHOR_NW; - witem->impl->size_pixels = FALSE; -} - -static void -ganv_widget_destroy(GtkObject* object) -{ - g_return_if_fail(object != NULL); - g_return_if_fail(GANV_IS_WIDGET(object)); - - GanvWidget* witem = GANV_WIDGET(object); - - if (witem->impl->widget && !witem->impl->in_destroy) { - g_signal_handler_disconnect(witem->impl->widget, witem->impl->destroy_id); - gtk_widget_destroy(witem->impl->widget); - witem->impl->widget = NULL; - } - - if (GTK_OBJECT_CLASS(parent_class)->destroy) { - (*GTK_OBJECT_CLASS(parent_class)->destroy)(object); - } -} - -static void -recalc_bounds(GanvWidget* witem) -{ - GanvItem* item = GANV_ITEM(witem); - - /* Get world coordinates */ - - double wx = witem->impl->x; - double wy = witem->impl->y; - ganv_item_i2w(item, &wx, &wy); - - /* Get canvas pixel coordinates */ - - ganv_canvas_w2c(item->impl->canvas, wx, wy, &witem->impl->cx, &witem->impl->cy); - - /* Anchor widget item */ - - switch (witem->impl->anchor) { - case GTK_ANCHOR_N: - case GTK_ANCHOR_CENTER: - case GTK_ANCHOR_S: - witem->impl->cx -= witem->impl->cwidth / 2; - break; - - case GTK_ANCHOR_NE: - case GTK_ANCHOR_E: - case GTK_ANCHOR_SE: - witem->impl->cx -= witem->impl->cwidth; - break; - - default: - break; - } - - switch (witem->impl->anchor) { - case GTK_ANCHOR_W: - case GTK_ANCHOR_CENTER: - case GTK_ANCHOR_E: - witem->impl->cy -= witem->impl->cheight / 2; - break; - - case GTK_ANCHOR_SW: - case GTK_ANCHOR_S: - case GTK_ANCHOR_SE: - witem->impl->cy -= witem->impl->cheight; - break; - - default: - break; - } - - /* Bounds */ - - item->impl->x1 = witem->impl->cx; - item->impl->y1 = witem->impl->cy; - item->impl->x2 = witem->impl->cx + witem->impl->cwidth; - item->impl->y2 = witem->impl->cy + witem->impl->cheight; - - int zoom_xofs, zoom_yofs; - ganv_canvas_get_zoom_offsets(item->impl->canvas, &zoom_xofs, &zoom_yofs); - if (witem->impl->widget) { - gtk_layout_move(GTK_LAYOUT(item->impl->canvas), witem->impl->widget, - witem->impl->cx + zoom_xofs, - witem->impl->cy + zoom_yofs); - } -} - -static void -do_destroy(GtkObject* object, gpointer data) -{ - GanvWidget* witem = GANV_WIDGET(data); - - witem->impl->in_destroy = TRUE; - gtk_object_destroy(GTK_OBJECT(data)); -} - -static void -ganv_widget_set_property(GObject* object, - guint param_id, - const GValue* value, - GParamSpec* pspec) -{ - GanvItem* item = GANV_ITEM(object); - GanvWidget* witem = GANV_WIDGET(object); - int update = FALSE; - int calc_bounds = FALSE; - GObject* obj; - - switch (param_id) { - case PROP_WIDGET: - if (witem->impl->widget) { - g_signal_handler_disconnect(witem->impl->widget, witem->impl->destroy_id); - gtk_container_remove(GTK_CONTAINER(item->impl->canvas), witem->impl->widget); - } - - obj = (GObject*)g_value_get_object(value); - if (obj) { - witem->impl->widget = GTK_WIDGET(obj); - witem->impl->destroy_id = g_signal_connect(obj, "destroy", - G_CALLBACK(do_destroy), - witem); - int zoom_xofs, zoom_yofs; - ganv_canvas_get_zoom_offsets(item->impl->canvas, &zoom_xofs, &zoom_yofs); - - gtk_layout_put(GTK_LAYOUT(item->impl->canvas), witem->impl->widget, - witem->impl->cx + zoom_xofs, - witem->impl->cy + zoom_yofs); - } - - update = TRUE; - break; - - case PROP_X: - if (witem->impl->x != g_value_get_double(value)) { - witem->impl->x = g_value_get_double(value); - calc_bounds = TRUE; - } - break; - - case PROP_Y: - if (witem->impl->y != g_value_get_double(value)) { - witem->impl->y = g_value_get_double(value); - calc_bounds = TRUE; - } - break; - - case PROP_WIDTH: - if (witem->impl->width != fabs(g_value_get_double(value))) { - witem->impl->width = fabs(g_value_get_double(value)); - update = TRUE; - } - break; - - case PROP_HEIGHT: - if (witem->impl->height != fabs(g_value_get_double(value))) { - witem->impl->height = fabs(g_value_get_double(value)); - update = TRUE; - } - break; - - case PROP_ANCHOR: - if (witem->impl->anchor != (GtkAnchorType)g_value_get_enum(value)) { - witem->impl->anchor = (GtkAnchorType)g_value_get_enum(value); - update = TRUE; - } - break; - - case PROP_SIZE_PIXELS: - if (witem->impl->size_pixels != g_value_get_boolean(value)) { - witem->impl->size_pixels = g_value_get_boolean(value); - update = TRUE; - } - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec); - break; - } - - if (update) { - (*GANV_ITEM_GET_CLASS(item)->update)(item, 0); - } - - if (calc_bounds) { - recalc_bounds(witem); - } -} - -static void -ganv_widget_get_property(GObject* object, - guint param_id, - GValue* value, - GParamSpec* pspec) -{ - g_return_if_fail(object != NULL); - g_return_if_fail(GANV_IS_WIDGET(object)); - - GanvWidget* witem = GANV_WIDGET(object); - - switch (param_id) { - case PROP_WIDGET: - g_value_set_object(value, (GObject*)witem->impl->widget); - break; - - case PROP_X: - g_value_set_double(value, witem->impl->x); - break; - - case PROP_Y: - g_value_set_double(value, witem->impl->y); - break; - - case PROP_WIDTH: - g_value_set_double(value, witem->impl->width); - break; - - case PROP_HEIGHT: - g_value_set_double(value, witem->impl->height); - break; - - case PROP_ANCHOR: - g_value_set_enum(value, witem->impl->anchor); - break; - - case PROP_SIZE_PIXELS: - g_value_set_boolean(value, witem->impl->size_pixels); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec); - break; - } -} - -static void -ganv_widget_update(GanvItem* item, int flags) -{ - GanvWidget* witem = GANV_WIDGET(item); - - if (parent_class->update) { - (*parent_class->update)(item, flags); - } - - if (witem->impl->widget) { - const double pixels_per_unit = ganv_canvas_get_zoom(item->impl->canvas); - if (witem->impl->size_pixels) { - witem->impl->cwidth = (int)(witem->impl->width + 0.5); - witem->impl->cheight = (int)(witem->impl->height + 0.5); - } else { - witem->impl->cwidth = (int)(witem->impl->width * pixels_per_unit + 0.5); - witem->impl->cheight = (int)(witem->impl->height * pixels_per_unit + 0.5); - } - - gtk_widget_set_size_request(witem->impl->widget, witem->impl->cwidth, witem->impl->cheight); - } else { - witem->impl->cwidth = 0.0; - witem->impl->cheight = 0.0; - } - - recalc_bounds(witem); -} - -static void -ganv_widget_draw(GanvItem* item, - cairo_t* cr, double cx, double cy, double cw, double ch) -{ - GanvWidget* witem = GANV_WIDGET(item); - - if (witem->impl->widget) { - gtk_widget_queue_draw(witem->impl->widget); - } -} - -static double -ganv_widget_point(GanvItem* item, double x, double y, GanvItem** actual_item) -{ - GanvWidget* witem = GANV_WIDGET(item); - - *actual_item = item; - - double x1, y1; - ganv_canvas_c2w(item->impl->canvas, witem->impl->cx, witem->impl->cy, &x1, &y1); - - const double pixels_per_unit = ganv_canvas_get_zoom(item->impl->canvas); - - double x2 = x1 + (witem->impl->cwidth - 1) / pixels_per_unit; - double y2 = y1 + (witem->impl->cheight - 1) / pixels_per_unit; - - /* Is point inside widget bounds? */ - - if ((x >= x1) && (y >= y1) && (x <= x2) && (y <= y2)) { - return 0.0; - } - - /* Point is outside widget bounds */ - - double dx; - if (x < x1) { - dx = x1 - x; - } else if (x > x2) { - dx = x - x2; - } else { - dx = 0.0; - } - - double dy; - if (y < y1) { - dy = y1 - y; - } else if (y > y2) { - dy = y - y2; - } else { - dy = 0.0; - } - - return sqrt(dx * dx + dy * dy); -} - -static void -ganv_widget_bounds(GanvItem* item, double* x1, double* y1, double* x2, double* y2) -{ - GanvWidget* witem = GANV_WIDGET(item); - - *x1 = witem->impl->x; - *y1 = witem->impl->y; - - switch (witem->impl->anchor) { - case GTK_ANCHOR_NW: - case GTK_ANCHOR_W: - case GTK_ANCHOR_SW: - break; - - case GTK_ANCHOR_N: - case GTK_ANCHOR_CENTER: - case GTK_ANCHOR_S: - *x1 -= witem->impl->width / 2.0; - break; - - case GTK_ANCHOR_NE: - case GTK_ANCHOR_E: - case GTK_ANCHOR_SE: - *x1 -= witem->impl->width; - break; - - default: - break; - } - - switch (witem->impl->anchor) { - case GTK_ANCHOR_NW: - case GTK_ANCHOR_N: - case GTK_ANCHOR_NE: - break; - - case GTK_ANCHOR_W: - case GTK_ANCHOR_CENTER: - case GTK_ANCHOR_E: - *y1 -= witem->impl->height / 2.0; - break; - - case GTK_ANCHOR_SW: - case GTK_ANCHOR_S: - case GTK_ANCHOR_SE: - *y1 -= witem->impl->height; - break; - - default: - break; - } - - *x2 = *x1 + witem->impl->width; - *y2 = *y1 + witem->impl->height; -} - -static void -ganv_widget_class_init(GanvWidgetClass* klass) -{ - GObjectClass* gobject_class = (GObjectClass*)klass; - GtkObjectClass* object_class = (GtkObjectClass*)klass; - GanvItemClass* item_class = (GanvItemClass*)klass; - - parent_class = (GanvItemClass*)g_type_class_peek_parent(klass); - - gobject_class->set_property = ganv_widget_set_property; - gobject_class->get_property = ganv_widget_get_property; - - g_object_class_install_property( - gobject_class, PROP_WIDGET, g_param_spec_object( - "widget", _("Widget"), - _("The widget to embed in this item."), - GTK_TYPE_WIDGET, - (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE))); - - g_object_class_install_property( - gobject_class, PROP_X, g_param_spec_double( - "x", _("x"), - _("The x coordinate of the anchor"), - -G_MAXDOUBLE, G_MAXDOUBLE, 0.0, - G_PARAM_READWRITE)); - - g_object_class_install_property( - gobject_class, PROP_Y, g_param_spec_double( - "y", _("y"), - _("The x coordinate of the anchor"), - -G_MAXDOUBLE, G_MAXDOUBLE, 0.0, - G_PARAM_READWRITE)); - - g_object_class_install_property( - gobject_class, PROP_WIDTH, g_param_spec_double( - "width", _("Width"), - _("The width of the widget."), - -G_MAXDOUBLE, G_MAXDOUBLE, 0.0, - G_PARAM_READWRITE)); - - g_object_class_install_property( - gobject_class, PROP_HEIGHT, g_param_spec_double( - "height", _("Height"), - _("The height of the widget."), - -G_MAXDOUBLE, G_MAXDOUBLE, 0.0, - G_PARAM_READWRITE)); - - g_object_class_install_property( - gobject_class, PROP_ANCHOR, g_param_spec_enum( - "anchor", _("Anchor"), - _("The anchor point of the widget."), - GTK_TYPE_ANCHOR_TYPE, - GTK_ANCHOR_NW, - G_PARAM_READWRITE)); - - g_object_class_install_property( - gobject_class, PROP_SIZE_PIXELS, g_param_spec_boolean( - "size-pixels", ("Size is in pixels"), - _("Specifies whether the widget size is specified in pixels or" - " canvas units. If it is in pixels, then the widget will not" - " be scaled when the canvas zoom factor changes. Otherwise," - " it will be scaled."), - FALSE, - G_PARAM_READWRITE)); - - object_class->destroy = ganv_widget_destroy; - - item_class->update = ganv_widget_update; - item_class->point = ganv_widget_point; - item_class->bounds = ganv_widget_bounds; - item_class->draw = ganv_widget_draw; -} |