diff options
| author | Alex Valavanis <valavanisalex@gmail.com> | 2012-02-26 21:46:12 +0000 |
|---|---|---|
| committer | Alex Valavanis <valavanisalex@gmail.com> | 2012-02-26 21:46:12 +0000 |
| commit | 5d67bb43568b52c35e281c8b28f051ff2000e9b8 (patch) | |
| tree | af0b0ca1f4f9a5cf0eb63117f2af3251505ca31e /src/widgets | |
| parent | Dutch translation: minor update (diff) | |
| download | inkscape-5d67bb43568b52c35e281c8b28f051ff2000e9b8.tar.gz inkscape-5d67bb43568b52c35e281c8b28f051ff2000e9b8.zip | |
Import deprecated GtkRuler API. Probably worth tidying :-)
Fixed bugs:
- https://launchpad.net/bugs/802125
(bzr r11023)
Diffstat (limited to 'src/widgets')
| -rw-r--r-- | src/widgets/desktop-widget.cpp | 24 | ||||
| -rw-r--r-- | src/widgets/ruler.cpp | 890 | ||||
| -rw-r--r-- | src/widgets/ruler.h | 94 |
3 files changed, 969 insertions, 39 deletions
diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index cd7031dea..a2f74bb75 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -367,7 +367,7 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) eventbox = gtk_event_box_new (); dtw->hruler = sp_hruler_new (); dtw->hruler_box = eventbox; - sp_ruler_set_metric (GTK_RULER (dtw->hruler), SP_PT); + sp_ruler_set_metric (GTK_DEPRECATED_RULER (dtw->hruler), SP_PT); gtk_widget_set_tooltip_text (dtw->hruler_box, gettext(sp_unit_get_plural (&sp_unit_get_by_id(SP_UNIT_PT)))); gtk_container_add (GTK_CONTAINER (eventbox), dtw->hruler); gtk_table_attach (GTK_TABLE (canvas_tbl), eventbox, 1, 2, 0, 1, (GtkAttachOptions)(GTK_FILL), (GtkAttachOptions)(GTK_FILL), @@ -380,7 +380,7 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) eventbox = gtk_event_box_new (); dtw->vruler = sp_vruler_new (); dtw->vruler_box = eventbox; - sp_ruler_set_metric (GTK_RULER (dtw->vruler), SP_PT); + sp_ruler_set_metric (GTK_DEPRECATED_RULER (dtw->vruler), SP_PT); gtk_widget_set_tooltip_text (dtw->vruler_box, gettext(sp_unit_get_plural (&sp_unit_get_by_id(SP_UNIT_PT)))); gtk_container_add (GTK_CONTAINER (eventbox), GTK_WIDGET (dtw->vruler)); gtk_table_attach (GTK_TABLE (canvas_tbl), eventbox, 0, 1, 1, 2, (GtkAttachOptions)(GTK_FILL), (GtkAttachOptions)(GTK_FILL), 0, @@ -1510,10 +1510,10 @@ SPDesktopWidget::viewSetPosition (Geom::Point p) Geom::Point const origin = ( p - ruler_origin ); gdouble hlower, hupper, hmax_range; gdouble vlower, vupper, vmax_range; - gtk_ruler_get_range(GTK_RULER(hruler), &hlower, &hupper, NULL, &hmax_range); - gtk_ruler_set_range(GTK_RULER(hruler), hlower, hupper, origin[Geom::X], hmax_range); - gtk_ruler_get_range(GTK_RULER(vruler), &vlower, &vupper, NULL, &vmax_range); - gtk_ruler_set_range(GTK_RULER(vruler), vlower, vupper, origin[Geom::Y], vmax_range); + gtk_deprecated_ruler_get_range(GTK_DEPRECATED_RULER(hruler), &hlower, &hupper, NULL, &hmax_range); + gtk_deprecated_ruler_set_range(GTK_DEPRECATED_RULER(hruler), hlower, hupper, origin[Geom::X], hmax_range); + gtk_deprecated_ruler_get_range(GTK_DEPRECATED_RULER(vruler), &vlower, &vupper, NULL, &vmax_range); + gtk_deprecated_ruler_set_range(GTK_DEPRECATED_RULER(vruler), vlower, vupper, origin[Geom::Y], vmax_range); } void @@ -1537,8 +1537,8 @@ sp_desktop_widget_update_hruler (SPDesktopWidget *dtw) double const scale = dtw->desktop->current_zoom(); double s = viewbox.min()[Geom::X] / scale - dtw->ruler_origin[Geom::X]; double e = viewbox.max()[Geom::X] / scale - dtw->ruler_origin[Geom::X]; - gtk_ruler_get_range(GTK_RULER(dtw->hruler), NULL, NULL, &position, NULL); - gtk_ruler_set_range(GTK_RULER(dtw->hruler), s, e, position, (e - s)); + gtk_deprecated_ruler_get_range(GTK_DEPRECATED_RULER(dtw->hruler), NULL, NULL, &position, NULL); + gtk_deprecated_ruler_set_range(GTK_DEPRECATED_RULER(dtw->hruler), s, e, position, (e - s)); } void @@ -1555,8 +1555,8 @@ sp_desktop_widget_update_vruler (SPDesktopWidget *dtw) double const scale = dtw->desktop->current_zoom(); double s = viewbox.min()[Geom::Y] / -scale - dtw->ruler_origin[Geom::Y]; double e = viewbox.max()[Geom::Y] / -scale - dtw->ruler_origin[Geom::Y]; - gtk_ruler_get_range(GTK_RULER(dtw->vruler), NULL, NULL, &position, NULL); - gtk_ruler_set_range(GTK_RULER(dtw->vruler), s, e, position, (e - s)); + gtk_deprecated_ruler_get_range(GTK_DEPRECATED_RULER(dtw->vruler), NULL, NULL, &position, NULL); + gtk_deprecated_ruler_set_range(GTK_DEPRECATED_RULER(dtw->vruler), s, e, position, (e - s)); } @@ -1568,8 +1568,8 @@ void SPDesktopWidget::namedviewModified(SPObject *obj, guint flags) this->dt2r = 1.0 / nv->doc_units->unittobase; this->ruler_origin = Geom::Point(0,0); //nv->gridorigin; Why was the grid origin used here? - sp_ruler_set_metric(GTK_RULER (this->vruler), nv->getDefaultMetric()); - sp_ruler_set_metric(GTK_RULER (this->hruler), nv->getDefaultMetric()); + sp_ruler_set_metric(GTK_DEPRECATED_RULER (this->vruler), nv->getDefaultMetric()); + sp_ruler_set_metric(GTK_DEPRECATED_RULER (this->hruler), nv->getDefaultMetric()); /* This loops through all the grandchildren of aux toolbox, * and for each that it finds, it performs an sp_search_by_data_recursive(), diff --git a/src/widgets/ruler.cpp b/src/widgets/ruler.cpp index 74384161e..8dbd771a6 100644 --- a/src/widgets/ruler.cpp +++ b/src/widgets/ruler.cpp @@ -22,13 +22,859 @@ #include "ruler.h" #include "unit-constants.h" #include "round.h" +#include <glibmm/i18n.h> + +#define GTK_PARAM_READWRITE G_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB #define MINIMUM_INCR 5 #define MAXIMUM_SUBDIVIDE 5 #define MAXIMUM_SCALES 10 + +#define ROUND(x) ((int) ((x) + 0.5)) + +enum { + PROP_0, + PROP_ORIENTATION, + PROP_LOWER, + PROP_UPPER, + PROP_POSITION, + PROP_MAX_SIZE, + PROP_METRIC +}; + +typedef struct _GtkDeprecatedRulerPrivate GtkDeprecatedRulerPrivate; + +struct _GtkDeprecatedRulerPrivate +{ + GtkOrientation orientation; +}; + +static void gtk_deprecated_ruler_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void gtk_deprecated_ruler_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void gtk_deprecated_ruler_realize (GtkWidget *widget); +static void gtk_deprecated_ruler_unrealize (GtkWidget *widget); +static void gtk_deprecated_ruler_size_request (GtkWidget *widget, + GtkRequisition *requisition); +static void gtk_deprecated_ruler_size_allocate (GtkWidget *widget, + GtkAllocation *allocation); +static gboolean gtk_deprecated_ruler_motion_notify (GtkWidget *widget, + GdkEventMotion *event); +static gboolean gtk_deprecated_ruler_expose (GtkWidget *widget, + GdkEventExpose *event); +static void gtk_deprecated_ruler_make_pixmap (GtkDeprecatedRuler *ruler); +static void gtk_deprecated_ruler_real_draw_ticks (GtkDeprecatedRuler *ruler); +static void gtk_deprecated_ruler_real_draw_pos (GtkDeprecatedRuler *ruler); + + +static const GtkDeprecatedRulerMetric ruler_metrics[] = +{ + { "Pixel", "Pi", 1.0, { 1, 2, 5, 10, 25, 50, 100, 250, 500, 1000 }, { 1, 5, 10, 50, 100 }}, + { "Inches", "In", 72.0, { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512 }, { 1, 2, 4, 8, 16 }}, + { "Centimeters", "Cn", 28.35, { 1, 2, 5, 10, 25, 50, 100, 250, 500, 1000 }, { 1, 5, 10, 50, 100 }}, +}; +#define GTK_DEPRECATED_RULER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_DEPRECATED_TYPE_RULER, GtkDeprecatedRulerPrivate)) + + +G_DEFINE_TYPE_WITH_CODE (GtkDeprecatedRuler, gtk_deprecated_ruler, GTK_TYPE_WIDGET, + G_IMPLEMENT_INTERFACE (GTK_TYPE_ORIENTABLE, + NULL)) + +static void +gtk_deprecated_ruler_class_init (GtkDeprecatedRulerClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + gobject_class->set_property = gtk_deprecated_ruler_set_property; + gobject_class->get_property = gtk_deprecated_ruler_get_property; + + widget_class->realize = gtk_deprecated_ruler_realize; + widget_class->unrealize = gtk_deprecated_ruler_unrealize; + widget_class->size_request = gtk_deprecated_ruler_size_request; + widget_class->size_allocate = gtk_deprecated_ruler_size_allocate; + widget_class->motion_notify_event = gtk_deprecated_ruler_motion_notify; + widget_class->expose_event = gtk_deprecated_ruler_expose; + + klass->draw_ticks = gtk_deprecated_ruler_real_draw_ticks; + klass->draw_pos = gtk_deprecated_ruler_real_draw_pos; + + g_object_class_override_property (gobject_class, + PROP_ORIENTATION, + "orientation"); + + g_object_class_install_property (gobject_class, + PROP_LOWER, + g_param_spec_double ("lower", + _("Lower"), + _("Lower limit of ruler"), + -G_MAXDOUBLE, + G_MAXDOUBLE, + 0.0, + static_cast<GParamFlags>(GTK_PARAM_READWRITE))); + + g_object_class_install_property (gobject_class, + PROP_UPPER, + g_param_spec_double ("upper", + _("Upper"), + _("Upper limit of ruler"), + -G_MAXDOUBLE, + G_MAXDOUBLE, + 0.0, + static_cast<GParamFlags>(GTK_PARAM_READWRITE))); + + g_object_class_install_property (gobject_class, + PROP_POSITION, + g_param_spec_double ("position", + _("Position"), + _("Position of mark on the ruler"), + -G_MAXDOUBLE, + G_MAXDOUBLE, + 0.0, + static_cast<GParamFlags>(GTK_PARAM_READWRITE))); + + g_object_class_install_property (gobject_class, + PROP_MAX_SIZE, + g_param_spec_double ("max-size", + _("Max Size"), + _("Maximum size of the ruler"), + -G_MAXDOUBLE, + G_MAXDOUBLE, + 0.0, + static_cast<GParamFlags>(GTK_PARAM_READWRITE))); + /** + * GtkDeprecatedRuler:metric: + * + * The metric used for the ruler. + */ + g_object_class_install_property (gobject_class, + PROP_METRIC, + g_param_spec_enum ("metric", + _("Metric"), + _("The metric used for the ruler"), + GTK_TYPE_METRIC_TYPE, + GTK_PIXELS, + static_cast<GParamFlags>(GTK_PARAM_READWRITE))); + + g_type_class_add_private (gobject_class, sizeof (GtkDeprecatedRulerPrivate)); +} + +static void +gtk_deprecated_ruler_init (GtkDeprecatedRuler *ruler) +{ + GtkWidget *widget = GTK_WIDGET (ruler); + GtkDeprecatedRulerPrivate *priv = GTK_DEPRECATED_RULER_GET_PRIVATE (ruler); + + priv->orientation = GTK_ORIENTATION_HORIZONTAL; + + widget->requisition.width = widget->style->xthickness * 2 + 1; + widget->requisition.height = widget->style->ythickness * 2 + RULER_WIDTH; + + ruler->backing_store = NULL; + ruler->xsrc = 0; + ruler->ysrc = 0; + ruler->slider_size = 0; + ruler->lower = 0; + ruler->upper = 0; + ruler->position = 0; + ruler->max_size = 0; + + gtk_deprecated_ruler_set_metric (ruler, GTK_PIXELS); +} + + +/** + * gtk_deprecated_ruler_set_range: + * @ruler: the gtkdeprecatedruler + * @lower: the lower limit of the ruler + * @upper: the upper limit of the ruler + * @position: the mark on the ruler + * @max_size: the maximum size of the ruler used when calculating the space to + * leave for the text + * + * This sets the range of the ruler. + */ +void +gtk_deprecated_ruler_set_range (GtkDeprecatedRuler *ruler, + gdouble lower, + gdouble upper, + gdouble position, + gdouble max_size) +{ + g_return_if_fail (GTK_DEPRECATED_IS_RULER (ruler)); + + g_object_freeze_notify (G_OBJECT (ruler)); + if (ruler->lower != lower) + { + ruler->lower = lower; + g_object_notify (G_OBJECT (ruler), "lower"); + } + if (ruler->upper != upper) + { + ruler->upper = upper; + g_object_notify (G_OBJECT (ruler), "upper"); + } + if (ruler->position != position) + { + ruler->position = position; + g_object_notify (G_OBJECT (ruler), "position"); + } + if (ruler->max_size != max_size) + { + ruler->max_size = max_size; + g_object_notify (G_OBJECT (ruler), "max-size"); + } + g_object_thaw_notify (G_OBJECT (ruler)); + + if (gtk_widget_is_drawable (GTK_WIDGET (ruler))) + gtk_widget_queue_draw (GTK_WIDGET (ruler)); +} + +/** + * gtk_deprecated_ruler_get_range: + * @ruler: a #GtkDeprecatedRuler + * @lower: (allow-none): location to store lower limit of the ruler, or %NULL + * @upper: (allow-none): location to store upper limit of the ruler, or %NULL + * @position: (allow-none): location to store the current position of the mark on the ruler, or %NULL + * @max_size: location to store the maximum size of the ruler used when calculating + * the space to leave for the text, or %NULL. + * + * Retrieves values indicating the range and current position of a #GtkDeprecatedRuler. + * See gtk_deprecated_ruler_set_range(). + **/ +void +gtk_deprecated_ruler_get_range (GtkDeprecatedRuler *ruler, + gdouble *lower, + gdouble *upper, + gdouble *position, + gdouble *max_size) +{ + g_return_if_fail (GTK_DEPRECATED_IS_RULER (ruler)); + + if (lower) + *lower = ruler->lower; + if (upper) + *upper = ruler->upper; + if (position) + *position = ruler->position; + if (max_size) + *max_size = ruler->max_size; +} + +static void +gtk_deprecated_ruler_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GtkDeprecatedRuler *ruler = GTK_DEPRECATED_RULER (object); + GtkDeprecatedRulerPrivate *priv = GTK_DEPRECATED_RULER_GET_PRIVATE (ruler); + + switch (prop_id) + { + case PROP_ORIENTATION: + priv->orientation = static_cast<GtkOrientation>(g_value_get_enum (value)); + gtk_widget_queue_resize (GTK_WIDGET (ruler)); + break; + case PROP_LOWER: + gtk_deprecated_ruler_set_range (ruler, g_value_get_double (value), ruler->upper, + ruler->position, ruler->max_size); + break; + case PROP_UPPER: + gtk_deprecated_ruler_set_range (ruler, ruler->lower, g_value_get_double (value), + ruler->position, ruler->max_size); + break; + case PROP_POSITION: + gtk_deprecated_ruler_set_range (ruler, ruler->lower, ruler->upper, + g_value_get_double (value), ruler->max_size); + break; + case PROP_MAX_SIZE: + gtk_deprecated_ruler_set_range (ruler, ruler->lower, ruler->upper, + ruler->position, g_value_get_double (value)); + break; + case PROP_METRIC: + gtk_deprecated_ruler_set_metric (ruler, static_cast<GtkMetricType>(g_value_get_enum (value))); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gtk_deprecated_ruler_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GtkDeprecatedRuler *ruler = GTK_DEPRECATED_RULER (object); + GtkDeprecatedRulerPrivate *priv = GTK_DEPRECATED_RULER_GET_PRIVATE (ruler); + + switch (prop_id) + { + case PROP_ORIENTATION: + g_value_set_enum (value, priv->orientation); + break; + case PROP_LOWER: + g_value_set_double (value, ruler->lower); + break; + case PROP_UPPER: + g_value_set_double (value, ruler->upper); + break; + case PROP_POSITION: + g_value_set_double (value, ruler->position); + break; + case PROP_MAX_SIZE: + g_value_set_double (value, ruler->max_size); + break; + case PROP_METRIC: + g_value_set_enum (value, gtk_deprecated_ruler_get_metric (ruler)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +void +gtk_deprecated_ruler_set_metric (GtkDeprecatedRuler *ruler, + GtkMetricType metric) +{ + g_return_if_fail (GTK_DEPRECATED_IS_RULER (ruler)); + + ruler->metric = (GtkDeprecatedRulerMetric *) &ruler_metrics[metric]; + + if (gtk_widget_is_drawable (GTK_WIDGET (ruler))) + gtk_widget_queue_draw (GTK_WIDGET (ruler)); + + g_object_notify (G_OBJECT (ruler), "metric"); +} + +/** + * gtk_deprecated_ruler_get_metric: + * @ruler: a #GtkDeprecatedRuler + * + * Gets the units used for a #GtkDeprecatedRuler. See gtk_deprecated_ruler_set_metric(). + * + * Return value: the units currently used for @ruler + **/ +GtkMetricType +gtk_deprecated_ruler_get_metric (GtkDeprecatedRuler *ruler) +{ + gint i; + + g_return_val_if_fail (GTK_DEPRECATED_IS_RULER (ruler), static_cast<GtkMetricType>(0)); + + for (i = 0; i < G_N_ELEMENTS (ruler_metrics); i++) + if (ruler->metric == &ruler_metrics[i]) + return static_cast<GtkMetricType>(i); + + g_assert_not_reached (); + + return static_cast<GtkMetricType>(0); +} + + +void +gtk_deprecated_ruler_draw_ticks (GtkDeprecatedRuler *ruler) +{ + g_return_if_fail (GTK_DEPRECATED_IS_RULER (ruler)); + + if (GTK_DEPRECATED_RULER_GET_CLASS (ruler)->draw_ticks) + GTK_DEPRECATED_RULER_GET_CLASS (ruler)->draw_ticks (ruler); +} + +void +gtk_deprecated_ruler_draw_pos (GtkDeprecatedRuler *ruler) +{ + g_return_if_fail (GTK_DEPRECATED_IS_RULER (ruler)); + + if (GTK_DEPRECATED_RULER_GET_CLASS (ruler)->draw_pos) + GTK_DEPRECATED_RULER_GET_CLASS (ruler)->draw_pos (ruler); +} + + +static void +gtk_deprecated_ruler_realize (GtkWidget *widget) +{ + GtkDeprecatedRuler *ruler; + GdkWindowAttr attributes; + gint attributes_mask; + + ruler = GTK_DEPRECATED_RULER (widget); + + gtk_widget_set_realized (widget, TRUE); + + attributes.window_type = GDK_WINDOW_CHILD; + attributes.x = widget->allocation.x; + attributes.y = widget->allocation.y; + attributes.width = widget->allocation.width; + attributes.height = widget->allocation.height; + attributes.wclass = GDK_INPUT_OUTPUT; + attributes.visual = gtk_widget_get_visual (widget); + attributes.colormap = gtk_widget_get_colormap (widget); + attributes.event_mask = gtk_widget_get_events (widget); + attributes.event_mask |= (GDK_EXPOSURE_MASK | + GDK_POINTER_MOTION_MASK | + GDK_POINTER_MOTION_HINT_MASK); + + attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; + + widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask); + gdk_window_set_user_data (widget->window, ruler); + + widget->style = gtk_style_attach (widget->style, widget->window); + gtk_style_set_background (widget->style, widget->window, GTK_STATE_ACTIVE); + + gtk_deprecated_ruler_make_pixmap (ruler); +} + +static void +gtk_deprecated_ruler_unrealize (GtkWidget *widget) +{ + GtkDeprecatedRuler *ruler = GTK_DEPRECATED_RULER (widget); + + if (ruler->backing_store) + { + g_object_unref (ruler->backing_store); + ruler->backing_store = NULL; + } + + GTK_WIDGET_CLASS (gtk_deprecated_ruler_parent_class)->unrealize (widget); +} + +static void +gtk_deprecated_ruler_size_request (GtkWidget *widget, + GtkRequisition *requisition) +{ + GtkDeprecatedRulerPrivate *priv = GTK_DEPRECATED_RULER_GET_PRIVATE (widget); + + if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) + { + requisition->width = widget->style->xthickness * 2 + 1; + requisition->height = widget->style->ythickness * 2 + RULER_WIDTH; + } + else + { + requisition->width = widget->style->xthickness * 2 + RULER_WIDTH; + requisition->height = widget->style->ythickness * 2 + 1; + } +} + +static void +gtk_deprecated_ruler_size_allocate (GtkWidget *widget, + GtkAllocation *allocation) +{ + GtkDeprecatedRuler *ruler = GTK_DEPRECATED_RULER (widget); + + widget->allocation = *allocation; + + if (gtk_widget_get_realized (widget)) + { + gdk_window_move_resize (widget->window, + allocation->x, allocation->y, + allocation->width, allocation->height); + + gtk_deprecated_ruler_make_pixmap (ruler); + } +} + +static gboolean +gtk_deprecated_ruler_motion_notify (GtkWidget *widget, + GdkEventMotion *event) +{ + GtkDeprecatedRuler *ruler = GTK_DEPRECATED_RULER (widget); + GtkDeprecatedRulerPrivate *priv = GTK_DEPRECATED_RULER_GET_PRIVATE (widget); + gint x; + gint y; + + gdk_event_request_motions (event); + x = event->x; + y = event->y; + + if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) + ruler->position = ruler->lower + ((ruler->upper - ruler->lower) * x) / widget->allocation.width; + else + ruler->position = ruler->lower + ((ruler->upper - ruler->lower) * y) / widget->allocation.height; + + g_object_notify (G_OBJECT (ruler), "position"); + + /* Make sure the ruler has been allocated already */ + if (ruler->backing_store != NULL) + gtk_deprecated_ruler_draw_pos (ruler); + + return FALSE; +} + +static gboolean +gtk_deprecated_ruler_expose (GtkWidget *widget, + GdkEventExpose *event) +{ + if (gtk_widget_is_drawable (widget)) + { + GtkDeprecatedRuler *ruler = GTK_DEPRECATED_RULER (widget); + cairo_t *cr; + + gtk_deprecated_ruler_draw_ticks (ruler); + + cr = gdk_cairo_create (widget->window); + gdk_cairo_set_source_pixmap (cr, ruler->backing_store, 0, 0); + gdk_cairo_rectangle (cr, &event->area); + cairo_fill (cr); + cairo_destroy (cr); + + gtk_deprecated_ruler_draw_pos (ruler); + } + + return FALSE; +} + +static void +gtk_deprecated_ruler_make_pixmap (GtkDeprecatedRuler *ruler) +{ + GtkWidget *widget; + gint width; + gint height; + + widget = GTK_WIDGET (ruler); + + if (ruler->backing_store) + { + gdk_drawable_get_size (ruler->backing_store, &width, &height); + if ((width == widget->allocation.width) && + (height == widget->allocation.height)) + return; + + g_object_unref (ruler->backing_store); + } + + ruler->backing_store = gdk_pixmap_new (widget->window, + widget->allocation.width, + widget->allocation.height, + -1); + + ruler->xsrc = 0; + ruler->ysrc = 0; +} + +static void +gtk_deprecated_ruler_real_draw_ticks (GtkDeprecatedRuler *ruler) +{ + GtkWidget *widget = GTK_WIDGET (ruler); + GtkDeprecatedRulerPrivate *priv = GTK_DEPRECATED_RULER_GET_PRIVATE (ruler); + cairo_t *cr; + gint i, j; + gint width, height; + gint xthickness; + gint ythickness; + gint length, ideal_length; + gdouble lower, upper; /* Upper and lower limits, in ruler units */ + gdouble increment; /* Number of pixels per unit */ + gint scale; /* Number of units per major unit */ + gdouble subd_incr; + gdouble start, end, cur; + gchar unit_str[32]; + gint digit_height; + gint digit_offset; + gint text_width; + gint text_height; + gint pos; + PangoLayout *layout; + PangoRectangle logical_rect, ink_rect; + + if (!gtk_widget_is_drawable (widget)) + return; + + xthickness = widget->style->xthickness; + ythickness = widget->style->ythickness; + + layout = gtk_widget_create_pango_layout (widget, "012456789"); + pango_layout_get_extents (layout, &ink_rect, &logical_rect); + + digit_height = PANGO_PIXELS (ink_rect.height) + 2; + digit_offset = ink_rect.y; + + if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) + { + width = widget->allocation.width; + height = widget->allocation.height - ythickness * 2; + } + else + { + width = widget->allocation.height; + height = widget->allocation.width - ythickness * 2; + } + +#define DETAILE(priv) (priv->orientation == GTK_ORIENTATION_HORIZONTAL ? "hruler" : "vruler"); + + gtk_paint_box (widget->style, ruler->backing_store, + GTK_STATE_NORMAL, GTK_SHADOW_OUT, + NULL, widget, + priv->orientation == GTK_ORIENTATION_HORIZONTAL ? + "hruler" : "vruler", + 0, 0, + widget->allocation.width, widget->allocation.height); + + cr = gdk_cairo_create (ruler->backing_store); + gdk_cairo_set_source_color (cr, &widget->style->fg[widget->state]); + + if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) + { + cairo_rectangle (cr, + xthickness, + height + ythickness, + widget->allocation.width - 2 * xthickness, + 1); + } + else + { + cairo_rectangle (cr, + height + xthickness, + ythickness, + 1, + widget->allocation.height - 2 * ythickness); + } + + upper = ruler->upper / ruler->metric->pixels_per_unit; + lower = ruler->lower / ruler->metric->pixels_per_unit; + + if ((upper - lower) == 0) + goto out; + + increment = (gdouble) width / (upper - lower); + + /* determine the scale H + * We calculate the text size as for the vruler instead of using + * text_width = gdk_string_width(font, unit_str), so that the result + * for the scale looks consistent with an accompanying vruler + */ + /* determine the scale V + * use the maximum extents of the ruler to determine the largest + * possible number to be displayed. Calculate the height in pixels + * of this displayed text. Use this height to find a scale which + * leaves sufficient room for drawing the ruler. + */ + scale = ceil (ruler->max_size / ruler->metric->pixels_per_unit); + g_snprintf (unit_str, sizeof (unit_str), "%d", scale); + + if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) + { + text_width = strlen (unit_str) * digit_height + 1; + + for (scale = 0; scale < MAXIMUM_SCALES; scale++) + if (ruler->metric->ruler_scale[scale] * fabs(increment) > 2 * text_width) + break; + } + else + { + text_height = strlen (unit_str) * digit_height + 1; + + for (scale = 0; scale < MAXIMUM_SCALES; scale++) + if (ruler->metric->ruler_scale[scale] * fabs(increment) > 2 * text_height) + break; + } + + if (scale == MAXIMUM_SCALES) + scale = MAXIMUM_SCALES - 1; + + /* drawing starts here */ + length = 0; + for (i = MAXIMUM_SUBDIVIDE - 1; i >= 0; i--) + { + subd_incr = (gdouble) ruler->metric->ruler_scale[scale] / + (gdouble) ruler->metric->subdivide[i]; + if (subd_incr * fabs(increment) <= MINIMUM_INCR) + continue; + + /* Calculate the length of the tickmarks. Make sure that + * this length increases for each set of ticks + */ + ideal_length = height / (i + 1) - 1; + if (ideal_length > ++length) + length = ideal_length; + + if (lower < upper) + { + start = floor (lower / subd_incr) * subd_incr; + end = ceil (upper / subd_incr) * subd_incr; + } + else + { + start = floor (upper / subd_incr) * subd_incr; + end = ceil (lower / subd_incr) * subd_incr; + } + + for (cur = start; cur <= end; cur += subd_incr) + { + pos = ROUND ((cur - lower) * increment); + + if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) + { + cairo_rectangle (cr, + pos, height + ythickness - length, + 1, length); + } + else + { + cairo_rectangle (cr, + height + xthickness - length, pos, + length, 1); + } + + /* draw label */ + if (i == 0) + { + g_snprintf (unit_str, sizeof (unit_str), "%d", (int) cur); + + if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) + { + pango_layout_set_text (layout, unit_str, -1); + pango_layout_get_extents (layout, &logical_rect, NULL); + + gtk_paint_layout (widget->style, + ruler->backing_store, + gtk_widget_get_state (widget), + FALSE, + NULL, + widget, + "hruler", + pos + 2, ythickness + PANGO_PIXELS (logical_rect.y - digit_offset), + layout); + } + else + { + for (j = 0; j < (int) strlen (unit_str); j++) + { + pango_layout_set_text (layout, unit_str + j, 1); + pango_layout_get_extents (layout, NULL, &logical_rect); + + gtk_paint_layout (widget->style, + ruler->backing_store, + gtk_widget_get_state (widget), + FALSE, + NULL, + widget, + "vruler", + xthickness + 1, + pos + digit_height * j + 2 + PANGO_PIXELS (logical_rect.y - digit_offset), + layout); + } + } + } + } + } + + cairo_fill (cr); +out: + cairo_destroy (cr); + + g_object_unref (layout); +} + +static void +gtk_deprecated_ruler_real_draw_pos (GtkDeprecatedRuler *ruler) +{ + GtkWidget *widget = GTK_WIDGET (ruler); + GtkDeprecatedRulerPrivate *priv = GTK_DEPRECATED_RULER_GET_PRIVATE (ruler); + gint x, y; + gint width, height; + gint bs_width, bs_height; + gint xthickness; + gint ythickness; + gdouble increment; + + if (gtk_widget_is_drawable (widget)) + { + xthickness = widget->style->xthickness; + ythickness = widget->style->ythickness; + width = widget->allocation.width; + height = widget->allocation.height; + + if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) + { + height -= ythickness * 2; + + bs_width = height / 2 + 2; + bs_width |= 1; /* make sure it's odd */ + bs_height = bs_width / 2 + 1; + } + else + { + width -= xthickness * 2; + + bs_height = width / 2 + 2; + bs_height |= 1; /* make sure it's odd */ + bs_width = bs_height / 2 + 1; + } + + if ((bs_width > 0) && (bs_height > 0)) + { + cairo_t *cr = gdk_cairo_create (widget->window); + + /* If a backing store exists, restore the ruler */ + if (ruler->backing_store) + { + cairo_t *cr = gdk_cairo_create (widget->window); + + gdk_cairo_set_source_pixmap (cr, ruler->backing_store, 0, 0); + cairo_rectangle (cr, ruler->xsrc, ruler->ysrc, bs_width, bs_height); + cairo_fill (cr); + + cairo_destroy (cr); + } + + if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) + { + increment = (gdouble) width / (ruler->upper - ruler->lower); + + x = ROUND ((ruler->position - ruler->lower) * increment) + (xthickness - bs_width) / 2 - 1; + y = (height + bs_height) / 2 + ythickness; + } + else + { + increment = (gdouble) height / (ruler->upper - ruler->lower); + + x = (width + bs_width) / 2 + xthickness; + y = ROUND ((ruler->position - ruler->lower) * increment) + (ythickness - bs_height) / 2 - 1; + } + + gdk_cairo_set_source_color (cr, &widget->style->fg[widget->state]); + + cairo_move_to (cr, x, y); + + if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) + { + cairo_line_to (cr, x + bs_width / 2.0, y + bs_height); + cairo_line_to (cr, x + bs_width, y); + } + else + { + cairo_line_to (cr, x + bs_width, y + bs_height / 2.0); + cairo_line_to (cr, x, y + bs_height); + } + + cairo_fill (cr); + + cairo_destroy (cr); + + ruler->xsrc = x; + ruler->ysrc = y; + } + } +} + + + + + #define UNUSED_PIXELS 2 // There appear to be two pixels that are not being used at each end of the ruler -static void sp_ruler_common_draw_ticks (GtkRuler *ruler); +static void sp_ruler_common_draw_ticks (GtkDeprecatedRuler *ruler); static void sp_hruler_class_init (SPHRulerClass *klass); static void sp_hruler_init (SPHRuler *hruler); @@ -54,7 +900,7 @@ sp_hruler_get_type (void) NULL }; - hruler_type = g_type_register_static (gtk_ruler_get_type (), "SPHRuler", &hruler_info, (GTypeFlags)0); + hruler_type = g_type_register_static (gtk_deprecated_ruler_get_type (), "SPHRuler", &hruler_info, (GTypeFlags)0); } return hruler_type; @@ -64,12 +910,12 @@ static void sp_hruler_class_init (SPHRulerClass *klass) { GtkWidgetClass *widget_class; - GtkRulerClass *ruler_class; + GtkDeprecatedRulerClass *ruler_class; hruler_parent_class = (GtkWidgetClass *) g_type_class_peek_parent (klass); widget_class = (GtkWidgetClass*) klass; - ruler_class = (GtkRulerClass*) klass; + ruler_class = (GtkDeprecatedRulerClass*) klass; widget_class->motion_notify_event = sp_hruler_motion_notify; @@ -101,7 +947,7 @@ static gint sp_hruler_motion_notify (GtkWidget *widget, GdkEventMotion *event) { - GtkRuler *ruler; + GtkDeprecatedRuler *ruler; gdouble lower, upper, max_size; GtkAllocation allocation; @@ -109,13 +955,13 @@ sp_hruler_motion_notify (GtkWidget *widget, g_return_val_if_fail (SP_IS_HRULER (widget), FALSE); g_return_val_if_fail (event != NULL, FALSE); - ruler = GTK_RULER (widget); - gtk_ruler_get_range (ruler, &lower, &upper, NULL, &max_size); + ruler = GTK_DEPRECATED_RULER (widget); + gtk_deprecated_ruler_get_range (ruler, &lower, &upper, NULL, &max_size); gtk_widget_get_allocation (widget, &allocation); double x = event->x; //Although event->x is double according to the docs, it only appears to return integers double pos = lower + (upper - lower) * (x + UNUSED_PIXELS) / (allocation.width + 2*UNUSED_PIXELS); - gtk_ruler_set_range(ruler, lower, upper, pos, max_size); + gtk_deprecated_ruler_set_range(ruler, lower, upper, pos, max_size); return FALSE; } @@ -148,7 +994,7 @@ sp_vruler_get_type (void) NULL }; - vruler_type = g_type_register_static (gtk_ruler_get_type (), "SPVRuler", &vruler_info, (GTypeFlags)0); + vruler_type = g_type_register_static (gtk_deprecated_ruler_get_type (), "SPVRuler", &vruler_info, (GTypeFlags)0); } return vruler_type; @@ -158,12 +1004,12 @@ static void sp_vruler_class_init (SPVRulerClass *klass) { GtkWidgetClass *widget_class; - GtkRulerClass *ruler_class; + GtkDeprecatedRulerClass *ruler_class; vruler_parent_class = (GtkWidgetClass *) g_type_class_peek_parent (klass); widget_class = (GtkWidgetClass*) klass; - ruler_class = (GtkRulerClass*) klass; + ruler_class = (GtkDeprecatedRulerClass*) klass; widget_class->motion_notify_event = sp_vruler_motion_notify; widget_class->size_request = sp_vruler_size_request; @@ -198,7 +1044,7 @@ static gint sp_vruler_motion_notify (GtkWidget *widget, GdkEventMotion *event) { - GtkRuler *ruler; + GtkDeprecatedRuler *ruler; gdouble lower, upper, max_size; GtkAllocation allocation; @@ -206,13 +1052,13 @@ sp_vruler_motion_notify (GtkWidget *widget, g_return_val_if_fail (SP_IS_VRULER (widget), FALSE); g_return_val_if_fail (event != NULL, FALSE); - ruler = GTK_RULER (widget); - gtk_ruler_get_range (ruler, &lower, &upper, NULL, &max_size); + ruler = GTK_DEPRECATED_RULER (widget); + gtk_deprecated_ruler_get_range (ruler, &lower, &upper, NULL, &max_size); gtk_widget_get_allocation (widget, &allocation); double y = event->y; //Although event->y is double according to the docs, it only appears to return integers double pos = lower + (upper - lower) * (y + UNUSED_PIXELS) / (allocation.height + 2*UNUSED_PIXELS); - gtk_ruler_set_range(ruler, lower, upper, pos, max_size); + gtk_deprecated_ruler_set_range(ruler, lower, upper, pos, max_size); return FALSE; } @@ -225,7 +1071,7 @@ sp_vruler_size_request (GtkWidget *widget, GtkRequisition *requisition) } static void -sp_ruler_common_draw_ticks(GtkRuler *ruler) +sp_ruler_common_draw_ticks(GtkDeprecatedRuler *ruler) { gint width = 0; gint height = 0; @@ -274,7 +1120,7 @@ sp_ruler_common_draw_ticks(GtkRuler *ruler) gdouble ruler_upper = 0; gdouble ruler_lower = 0; gdouble max_size = 0; - gtk_ruler_get_range(ruler, &ruler_lower, &ruler_upper, NULL, &max_size); + gtk_deprecated_ruler_get_range(ruler, &ruler_lower, &ruler_upper, NULL, &max_size); gdouble upper = ruler_upper / ruler->metric->pixels_per_unit; // upper and lower are expressed in ruler units gdouble lower = ruler_lower / ruler->metric->pixels_per_unit; /* "pixels_per_unit" should be "points_per_unit". This is the size of the unit @@ -387,9 +1233,9 @@ sp_ruler_common_draw_ticks(GtkRuler *ruler) } } -// Note: const casts are due to GtkRuler being const-broken and not scheduled for any more fixes. +// Note: const casts are due to GtkDeprecatedRuler being const-broken and not scheduled for any more fixes. /// Ruler metrics. -static GtkRulerMetric const sp_ruler_metrics[] = { +static GtkDeprecatedRulerMetric const sp_ruler_metrics[] = { // NOTE: the order of records in this struct must correspond to the SPMetric enum. {const_cast<gchar*>("NONE"), const_cast<gchar*>(""), 1, { 1, 2, 5, 10, 25, 50, 100, 250, 500, 1000 }, { 1, 5, 10, 50, 100 }}, {const_cast<gchar*>("millimeters"), const_cast<gchar*>("mm"), PX_PER_MM, { 1, 2, 5, 10, 25, 50, 100, 250, 500, 1000 }, { 1, 5, 10, 50, 100 }}, @@ -403,17 +1249,17 @@ static GtkRulerMetric const sp_ruler_metrics[] = { }; void -sp_ruler_set_metric (GtkRuler *ruler, +sp_ruler_set_metric (GtkDeprecatedRuler *ruler, SPMetric metric) { g_return_if_fail (ruler != NULL); - g_return_if_fail (GTK_IS_RULER (ruler)); + g_return_if_fail (GTK_DEPRECATED_IS_RULER (ruler)); g_return_if_fail((unsigned) metric < G_N_ELEMENTS(sp_ruler_metrics)); if (metric == 0) return; - ruler->metric = const_cast<GtkRulerMetric *>(&sp_ruler_metrics[metric]); + ruler->metric = const_cast<GtkDeprecatedRulerMetric *>(&sp_ruler_metrics[metric]); if (gtk_widget_is_drawable (GTK_WIDGET (ruler))) gtk_widget_queue_draw (GTK_WIDGET (ruler)); diff --git a/src/widgets/ruler.h b/src/widgets/ruler.h index a774f12ef..3ead23d96 100644 --- a/src/widgets/ruler.h +++ b/src/widgets/ruler.h @@ -18,8 +18,92 @@ #include <iostream> #include <glib.h> +#define GTK_DEPRECATED_TYPE_RULER (gtk_deprecated_ruler_get_type ()) +#define GTK_DEPRECATED_RULER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_DEPRECATED_TYPE_RULER, GtkDeprecatedRuler)) +#define GTK_DEPRECATED_RULER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_DEPRECATED_TYPE_RULER, GtkDeprecatedRulerClass)) +#define GTK_DEPRECATED_IS_RULER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_DEPRECATED_TYPE_RULER)) +#define GTK_DEPRECATED_IS_RULER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_DEPRECATED_TYPE_RULER)) +#define GTK_DEPRECATED_RULER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_DEPRECATED_TYPE_RULER, GtkDeprecatedRulerClass)) -void sp_ruler_set_metric (GtkRuler * ruler, SPMetric metric); + +typedef struct _GtkDeprecatedRuler GtkDeprecatedRuler; +typedef struct _GtkDeprecatedRulerClass GtkDeprecatedRulerClass; +typedef struct _GtkDeprecatedRulerMetric GtkDeprecatedRulerMetric; + +/* All distances below are in 1/72nd's of an inch. (According to + * Adobe that's a point, but points are really 1/72.27 in.) + */ +struct _GtkDeprecatedRuler +{ + GtkWidget widget; + + GdkPixmap *GSEAL (backing_store); + GdkGC *GSEAL (non_gr_exp_gc); /* unused */ + GtkDeprecatedRulerMetric *GSEAL (metric); + gint GSEAL (xsrc); + gint GSEAL (ysrc); + gint GSEAL (slider_size); + + /* The upper limit of the ruler (in points) */ + gdouble GSEAL (lower); + /* The lower limit of the ruler */ + gdouble GSEAL (upper); + /* The position of the mark on the ruler */ + gdouble GSEAL (position); + /* The maximum size of the ruler */ + gdouble GSEAL (max_size); +}; + +struct _GtkDeprecatedRulerClass +{ + GtkWidgetClass parent_class; + + void (* draw_ticks) (GtkDeprecatedRuler *ruler); + void (* draw_pos) (GtkDeprecatedRuler *ruler); + + /* Padding for future expansion */ + void (*_gtk_reserved1) (void); + void (*_gtk_reserved2) (void); + void (*_gtk_reserved3) (void); + void (*_gtk_reserved4) (void); +}; + +struct _GtkDeprecatedRulerMetric +{ + gchar *metric_name; + gchar *abbrev; + /* This should be points_per_unit. This is the size of the unit + * in 1/72nd's of an inch and has nothing to do with screen pixels */ + gdouble pixels_per_unit; + gdouble ruler_scale[10]; + gint subdivide[5]; /* five possible modes of subdivision */ +}; + + +GType gtk_deprecated_ruler_get_type (void) G_GNUC_CONST; +void gtk_deprecated_ruler_set_metric (GtkDeprecatedRuler *ruler, + GtkMetricType metric); +GtkMetricType gtk_deprecated_ruler_get_metric (GtkDeprecatedRuler *ruler); +void gtk_deprecated_ruler_set_range (GtkDeprecatedRuler *ruler, + gdouble lower, + gdouble upper, + gdouble position, + gdouble max_size); +void gtk_deprecated_ruler_get_range (GtkDeprecatedRuler *ruler, + gdouble *lower, + gdouble *upper, + gdouble *position, + gdouble *max_size); + +void gtk_deprecated_ruler_draw_ticks (GtkDeprecatedRuler *ruler); +void gtk_deprecated_ruler_draw_pos (GtkDeprecatedRuler *ruler); + + + + + + +void sp_ruler_set_metric (GtkDeprecatedRuler * ruler, SPMetric metric); #define SP_HRULER(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, sp_hruler_get_type (), SPHRuler) @@ -29,12 +113,12 @@ void sp_ruler_set_metric (GtkRuler * ruler, SPMetric metric); struct SPHRuler { - GtkRuler ruler; + GtkDeprecatedRuler ruler; }; struct SPHRulerClass { - GtkRulerClass parent_class; + GtkDeprecatedRulerClass parent_class; }; @@ -54,12 +138,12 @@ GtkWidget* sp_hruler_new (void); struct SPVRuler { - GtkRuler ruler; + GtkDeprecatedRuler ruler; }; struct SPVRulerClass { - GtkRulerClass parent_class; + GtkDeprecatedRulerClass parent_class; }; |
