diff options
| author | Jabier Arraiza Cenoz <jabier.arraiza@marker.es> | 2012-12-24 07:07:34 +0000 |
|---|---|---|
| committer | Jabiertxo Arraiza Cenoz <jtx@jtx.marker.es> | 2012-12-24 07:07:34 +0000 |
| commit | 151539ee2fdfdc417a691ba1d51e129036687cff (patch) | |
| tree | 6be4d0f9f0516f99083506feede6a0806c2b8537 /src/widgets/ruler.cpp | |
| parent | Going to merge (diff) | |
| parent | extensions. function plotter. patch by ~suv for clip rectangle (Bug 492103) (diff) | |
| download | inkscape-151539ee2fdfdc417a691ba1d51e129036687cff.tar.gz inkscape-151539ee2fdfdc417a691ba1d51e129036687cff.zip | |
Merge from branch
(bzr r11950.1.6)
Diffstat (limited to 'src/widgets/ruler.cpp')
| -rw-r--r-- | src/widgets/ruler.cpp | 718 |
1 files changed, 418 insertions, 300 deletions
diff --git a/src/widgets/ruler.cpp b/src/widgets/ruler.cpp index 5104d5a9d..57c62f881 100644 --- a/src/widgets/ruler.cpp +++ b/src/widgets/ruler.cpp @@ -37,11 +37,8 @@ struct _SPRulerPrivate GtkOrientation orientation; SPRulerMetric *metric; -#if GTK_CHECK_VERSION(3,0,0) + GdkWindow *input_window; cairo_surface_t *backing_store; -#else - GdkPixmap *backing_store; -#endif gint slider_size; gint xsrc; @@ -63,46 +60,44 @@ enum { PROP_METRIC }; -static void sp_ruler_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static void sp_ruler_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); -static void sp_ruler_realize (GtkWidget *widget); -static void sp_ruler_unrealize (GtkWidget *widget); -static void sp_ruler_size_request (GtkWidget *widget, - GtkRequisition *requisition); +static void sp_ruler_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void sp_ruler_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void sp_ruler_realize (GtkWidget *widget); +static void sp_ruler_unrealize (GtkWidget *widget); +static void sp_ruler_map (GtkWidget *widget); +static void sp_ruler_unmap (GtkWidget *widget); +static void sp_ruler_size_request (GtkWidget *widget, + GtkRequisition *requisition); #if GTK_CHECK_VERSION(3,0,0) -static void sp_ruler_get_preferred_width (GtkWidget *widget, - gint *minimal_width, - gint *natural_width); +static void sp_ruler_get_preferred_width (GtkWidget *widget, + gint *minimal_width, + gint *natural_width); -static void sp_ruler_get_preferred_height (GtkWidget *widget, - gint *minimal_height, - gint *natural_height); +static void sp_ruler_get_preferred_height (GtkWidget *widget, + gint *minimal_height, + gint *natural_height); #endif static void sp_ruler_size_allocate (GtkWidget *widget, GtkAllocation *allocation); static gboolean sp_ruler_motion_notify (GtkWidget *widget, GdkEventMotion *event); -#if GTK_CHECK_VERSION(3,0,0) static gboolean sp_ruler_draw (GtkWidget *widget, cairo_t *cr); -#else +#if !GTK_CHECK_VERSION(3,0,0) static gboolean sp_ruler_expose (GtkWidget *widget, GdkEventExpose *event); #endif -static void sp_ruler_make_pixmap (SPRuler *ruler); static void sp_ruler_draw_ticks (SPRuler *ruler); -static void sp_ruler_real_draw_ticks (SPRuler *ruler, - cairo_t *cr); -static void sp_ruler_real_draw_pos (SPRuler *ruler, - cairo_t *cr); +static void sp_ruler_draw_pos (SPRuler *ruler); +static void sp_ruler_make_pixmap (SPRuler *ruler); #define SP_RULER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), SP_TYPE_RULER, SPRulerPrivate)) @@ -128,33 +123,34 @@ G_DEFINE_TYPE_WITH_CODE (SPRuler, sp_ruler, GTK_TYPE_WIDGET, static void sp_ruler_class_init (SPRulerClass *klass) { - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); - gobject_class->set_property = sp_ruler_set_property; - gobject_class->get_property = sp_ruler_get_property; + object_class->set_property = sp_ruler_set_property; + object_class->get_property = sp_ruler_get_property; - widget_class->realize = sp_ruler_realize; - widget_class->unrealize = sp_ruler_unrealize; + widget_class->realize = sp_ruler_realize; + widget_class->unrealize = sp_ruler_unrealize; + widget_class->map = sp_ruler_map; + widget_class->unmap = sp_ruler_unmap; + widget_class->size_allocate = sp_ruler_size_allocate; #if GTK_CHECK_VERSION(3,0,0) - widget_class->get_preferred_width = sp_ruler_get_preferred_width; + widget_class->get_preferred_width = sp_ruler_get_preferred_width; widget_class->get_preferred_height = sp_ruler_get_preferred_height; - widget_class->draw = sp_ruler_draw; + widget_class->draw = sp_ruler_draw; #else - widget_class->size_request = sp_ruler_size_request; - widget_class->expose_event = sp_ruler_expose; + widget_class->size_request = sp_ruler_size_request; + widget_class->expose_event = sp_ruler_expose; #endif - widget_class->size_allocate = sp_ruler_size_allocate; widget_class->motion_notify_event = sp_ruler_motion_notify; - klass->draw_ticks = sp_ruler_real_draw_ticks; - klass->draw_pos = sp_ruler_real_draw_pos; + g_type_class_add_private (object_class, sizeof (SPRulerPrivate)); - g_object_class_override_property (gobject_class, + g_object_class_override_property (object_class, PROP_ORIENTATION, "orientation"); - g_object_class_install_property (gobject_class, + g_object_class_install_property (object_class, PROP_LOWER, g_param_spec_double ("lower", _("Lower"), @@ -164,7 +160,7 @@ sp_ruler_class_init (SPRulerClass *klass) 0.0, static_cast<GParamFlags>(GTK_PARAM_READWRITE))); - g_object_class_install_property (gobject_class, + g_object_class_install_property (object_class, PROP_UPPER, g_param_spec_double ("upper", _("Upper"), @@ -174,7 +170,7 @@ sp_ruler_class_init (SPRulerClass *klass) 0.0, static_cast<GParamFlags>(GTK_PARAM_READWRITE))); - g_object_class_install_property (gobject_class, + g_object_class_install_property (object_class, PROP_POSITION, g_param_spec_double ("position", _("Position"), @@ -184,7 +180,7 @@ sp_ruler_class_init (SPRulerClass *klass) 0.0, static_cast<GParamFlags>(GTK_PARAM_READWRITE))); - g_object_class_install_property (gobject_class, + g_object_class_install_property (object_class, PROP_MAX_SIZE, g_param_spec_double ("max-size", _("Max Size"), @@ -200,7 +196,7 @@ sp_ruler_class_init (SPRulerClass *klass) * * TODO: This should probably use g_param_spec_enum */ - g_object_class_install_property (gobject_class, + g_object_class_install_property (object_class, PROP_METRIC, g_param_spec_uint("metric", _("Metric"), @@ -208,60 +204,34 @@ sp_ruler_class_init (SPRulerClass *klass) 0, 8, SP_PX, static_cast<GParamFlags>(GTK_PARAM_READWRITE))); - - g_type_class_add_private (gobject_class, sizeof (SPRulerPrivate)); } static void sp_ruler_init (SPRuler *ruler) { - ruler->priv = G_TYPE_INSTANCE_GET_PRIVATE(ruler, - SP_TYPE_RULER, - SPRulerPrivate); - - SPRulerPrivate *priv = ruler->priv; - - priv->orientation = GTK_ORIENTATION_HORIZONTAL; - + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler); + + gtk_widget_set_has_window (GTK_WIDGET (ruler), FALSE); + + priv->orientation = GTK_ORIENTATION_HORIZONTAL; + priv->xsrc = 0; + priv->ysrc = 0; + priv->slider_size = 0; + priv->lower = 0; + priv->upper = 0; + priv->position = 0; + priv->max_size = 0; priv->backing_store = NULL; - priv->xsrc = 0; - priv->ysrc = 0; - priv->slider_size = 0; - priv->lower = 0; - priv->upper = 0; - priv->position = 0; - priv->max_size = 0; sp_ruler_set_metric(ruler, SP_PX); } /** - * sp_ruler_invalidate_ticks: - * @ruler: the ruler to invalidate - * - * For performance reasons, #SPRuler keeps a backbuffer containing the - * prerendered contents of the ticks. To cause a repaint of this buffer, - * call this function instead of gtk_widget_queue_draw(). - **/ -static void sp_ruler_invalidate_ticks(SPRuler *ruler) -{ - g_return_if_fail(SP_IS_RULER(ruler)); - - if(ruler->priv->backing_store == NULL) - return; - - sp_ruler_draw_ticks(ruler); - gtk_widget_queue_draw(GTK_WIDGET(ruler)); -} - - -/** * sp_ruler_set_range: - * @ruler: the gtkdeprecatedruler + * @ruler: the SPRuler * @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 * @@ -269,14 +239,15 @@ static void sp_ruler_invalidate_ticks(SPRuler *ruler) */ void sp_ruler_set_range (SPRuler *ruler, - gdouble lower, - gdouble upper, - gdouble position, - gdouble max_size) + gdouble lower, + gdouble upper, + gdouble max_size) { + SPRulerPrivate *priv; + g_return_if_fail (SP_IS_RULER (ruler)); - SPRulerPrivate *priv = ruler->priv; + priv = SP_RULER_GET_PRIVATE (ruler); g_object_freeze_notify (G_OBJECT (ruler)); if (priv->lower != lower) @@ -289,11 +260,6 @@ sp_ruler_set_range (SPRuler *ruler, priv->upper = upper; g_object_notify (G_OBJECT (ruler), "upper"); } - if (priv->position != position) - { - priv->position = position; - g_object_notify (G_OBJECT (ruler), "position"); - } if (priv->max_size != max_size) { priv->max_size = max_size; @@ -301,7 +267,7 @@ sp_ruler_set_range (SPRuler *ruler, } g_object_thaw_notify (G_OBJECT (ruler)); - sp_ruler_invalidate_ticks(ruler); + gtk_widget_queue_draw (GTK_WIDGET (ruler)); } /** @@ -309,7 +275,6 @@ sp_ruler_set_range (SPRuler *ruler, * @ruler: a #SPRuler * @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. * @@ -320,19 +285,18 @@ void sp_ruler_get_range (SPRuler *ruler, gdouble *lower, gdouble *upper, - gdouble *position, gdouble *max_size) { + SPRulerPrivate *priv; + g_return_if_fail (SP_IS_RULER (ruler)); - SPRulerPrivate *priv = ruler->priv; + priv = SP_RULER_GET_PRIVATE (ruler); if (lower) *lower = priv->lower; if (upper) *upper = priv->upper; - if (position) - *position = priv->position; if (max_size) *max_size = priv->max_size; } @@ -344,7 +308,7 @@ sp_ruler_set_property (GObject *object, GParamSpec *pspec) { SPRuler *ruler = SP_RULER (object); - SPRulerPrivate *priv = ruler->priv; + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler); switch (prop_id) { @@ -353,23 +317,28 @@ sp_ruler_set_property (GObject *object, gtk_widget_queue_resize (GTK_WIDGET (ruler)); break; case PROP_LOWER: - sp_ruler_set_range (ruler, g_value_get_double (value), priv->upper, - priv->position, priv->max_size); + sp_ruler_set_range (ruler, + g_value_get_double (value), + priv->upper, + priv->max_size); break; case PROP_UPPER: - sp_ruler_set_range (ruler, priv->lower, g_value_get_double (value), - priv->position, priv->max_size); + sp_ruler_set_range (ruler, + priv->lower, + g_value_get_double (value), + priv->max_size); break; case PROP_POSITION: - sp_ruler_set_range (ruler, priv->lower, priv->upper, - g_value_get_double (value), priv->max_size); + sp_ruler_set_position (ruler, g_value_get_double (value)); break; case PROP_MAX_SIZE: - sp_ruler_set_range (ruler, priv->lower, priv->upper, - priv->position, g_value_get_double (value)); + sp_ruler_set_range (ruler, + priv->lower, + priv->upper, + g_value_get_double (value)); break; case PROP_METRIC: - sp_ruler_set_metric(ruler, static_cast<SPMetric>(g_value_get_enum (value))); + sp_ruler_set_metric (ruler, static_cast<SPMetric>(g_value_get_enum (value))); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -384,7 +353,7 @@ sp_ruler_get_property (GObject *object, GParamSpec *pspec) { SPRuler *ruler = SP_RULER (object); - SPRulerPrivate *priv = ruler->priv; + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler); switch (prop_id) { @@ -424,7 +393,7 @@ sp_ruler_get_property (GObject *object, SPMetric sp_ruler_get_metric(SPRuler *ruler) { g_return_val_if_fail(SP_IS_RULER(ruler), static_cast<SPMetric>(0)); - SPRulerPrivate *priv = ruler->priv; + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler); for (size_t i = 0; i < G_N_ELEMENTS(sp_ruler_metrics); i++) { if (priv->metric == &sp_ruler_metrics[i]) { @@ -438,102 +407,124 @@ SPMetric sp_ruler_get_metric(SPRuler *ruler) } -static void sp_ruler_draw_ticks(SPRuler *ruler) +static void +sp_ruler_realize (GtkWidget *widget) { - g_return_if_fail(SP_IS_RULER(ruler)); - SPRulerPrivate *priv = ruler->priv; + SPRuler *ruler = SP_RULER (widget); + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler); + GtkAllocation allocation; + GdkWindowAttr attributes; + gint attributes_mask; + GTK_WIDGET_CLASS (sp_ruler_parent_class)->realize (widget); + + gtk_widget_get_allocation (widget, &allocation); + + attributes.window_type = GDK_WINDOW_CHILD; + attributes.x = allocation.x; + attributes.y = allocation.y; + attributes.width = allocation.width; + attributes.height = allocation.height; + attributes.wclass = GDK_INPUT_ONLY; #if GTK_CHECK_VERSION(3,0,0) - cairo_t *cr = cairo_create(priv->backing_store); + attributes.event_mask = (gtk_widget_get_events (widget) | + GDK_EXPOSURE_MASK | + GDK_POINTER_MOTION_MASK | + GDK_POINTER_MOTION_HINT_MASK); #else - cairo_t *cr = gdk_cairo_create(priv->backing_store); + attributes.event_mask = (gtk_widget_get_events (widget) | + GDK_EXPOSURE_MASK | + GDK_POINTER_MOTION_MASK); #endif - if (SP_RULER_GET_CLASS(ruler)->draw_ticks) - SP_RULER_GET_CLASS(ruler)->draw_ticks(ruler, cr); + attributes_mask = GDK_WA_X | GDK_WA_Y; - cairo_destroy(cr); -} + priv->input_window = gdk_window_new (gtk_widget_get_parent_window (widget), + &attributes, attributes_mask); + gdk_window_set_user_data (priv->input_window, ruler); + sp_ruler_make_pixmap (ruler); +} -static void sp_ruler_realize(GtkWidget *widget) +static void +sp_ruler_unrealize(GtkWidget *widget) { - GtkAllocation allocation; - SPRuler *ruler; - GdkWindow *window; - GdkWindowAttr attributes; - gint attributes_mask; + SPRuler *ruler = SP_RULER (widget); + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler); - ruler = SP_RULER (widget); + if (priv->backing_store) + { + cairo_surface_destroy (priv->backing_store); + priv->backing_store = NULL; + } - gtk_widget_set_realized (widget, TRUE); + if (priv->input_window) + { + gdk_window_destroy (priv->input_window); + priv->input_window = NULL; + } - gtk_widget_get_allocation(widget, &allocation); + GTK_WIDGET_CLASS (sp_ruler_parent_class)->unrealize (widget); +} - attributes.window_type = GDK_WINDOW_CHILD; - attributes.x = allocation.x; - attributes.y = allocation.y; - attributes.width = allocation.width; - attributes.height = allocation.height; - attributes.wclass = GDK_INPUT_OUTPUT; - attributes.visual = gtk_widget_get_visual (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; - - window = gdk_window_new(gtk_widget_get_parent_window (widget), - &attributes, attributes_mask); - gtk_widget_set_window(widget, window); - gdk_window_set_user_data(window, ruler); +static void +sp_ruler_map (GtkWidget *widget) +{ + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (widget); -#if GTK_CHECK_VERSION(3,0,0) - gtk_style_context_set_background(gtk_widget_get_style_context(widget), - window); -#else - gtk_widget_style_attach(widget); - gtk_style_set_background(gtk_widget_get_style(widget), - window, GTK_STATE_ACTIVE); -#endif + GTK_WIDGET_CLASS (sp_ruler_parent_class)->map (widget); - sp_ruler_make_pixmap (ruler); + if (priv->input_window) + gdk_window_show (priv->input_window); } -static void sp_ruler_unrealize(GtkWidget *widget) +static void +sp_ruler_unmap (GtkWidget *widget) { - SPRuler *ruler = SP_RULER (widget); - SPRulerPrivate *priv = ruler->priv; - - if (priv->backing_store) - { -#if GTK_CHECK_VERSION(3,0,0) - cairo_surface_destroy(priv->backing_store); -#else - g_object_unref(priv->backing_store); -#endif - priv->backing_store = NULL; - } + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (widget); - GTK_WIDGET_CLASS (sp_ruler_parent_class)->unrealize (widget); + if (priv->input_window) + gdk_window_hide (priv->input_window); + + GTK_WIDGET_CLASS (sp_ruler_parent_class)->unmap (widget); } static void sp_ruler_size_request(GtkWidget *widget, GtkRequisition *requisition) { - SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (widget); - GtkStyle *style = gtk_widget_get_style(widget); + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (widget); + +#if GTK_CHECK_VERSION(3,0,0) + GtkStyleContext *context = gtk_widget_get_style_context (widget); + GtkBorder border; + + gtk_style_context_get_border (context, static_cast<GtkStateFlags>(0), &border); + + requisition->width = border.left + border.right; + requisition->height = border.top + border.bottom; +#else + GtkStyle *style = gtk_widget_get_style(widget); +#endif if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) { +#if GTK_CHECK_VERSION(3,0,0) + requisition->width += 1; + requisition->height += RULER_WIDTH; +#else requisition->width = style->xthickness * 2 + 1; requisition->height = style->ythickness * 2 + RULER_WIDTH; +#endif } else { +#if GTK_CHECK_VERSION(3,0,0) + requisition->width += RULER_WIDTH; + requisition->height += 1; +#else requisition->width = style->xthickness * 2 + RULER_WIDTH; requisition->height = style->ythickness * 2 + 1; +#endif } } @@ -553,112 +544,128 @@ static void sp_ruler_get_preferred_height(GtkWidget *widget, gint *minimal_heigh } #endif -static void sp_ruler_size_allocate(GtkWidget *widget, GtkAllocation *allocation) +static void +sp_ruler_size_allocate (GtkWidget *widget, + GtkAllocation *allocation) { - SPRuler *ruler = SP_RULER(widget); - GtkAllocation old_allocation; - gtk_widget_get_allocation(widget, &old_allocation); - - gboolean resized = (old_allocation.width != allocation->width || - old_allocation.height != allocation->height); + SPRuler *ruler = SP_RULER(widget); + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler); gtk_widget_set_allocation(widget, allocation); if (gtk_widget_get_realized (widget)) { - gdk_window_move_resize(gtk_widget_get_window(widget), - allocation->x, allocation->y, - allocation->width, allocation->height); - - if(resized) - sp_ruler_make_pixmap (ruler); + gdk_window_move_resize (priv->input_window, + allocation->x, allocation->y, + allocation->width, allocation->height); + + sp_ruler_make_pixmap (ruler); } } -#if GTK_CHECK_VERSION(3,0,0) -static gboolean sp_ruler_draw(GtkWidget *widget, - cairo_t *cr) -#else + +#if !GTK_CHECK_VERSION(3,0,0) static gboolean sp_ruler_expose(GtkWidget *widget, GdkEventExpose *event) +{ + cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(widget)); + GtkAllocation allocation; + + gdk_cairo_region (cr, event->region); + cairo_clip (cr); + + gtk_widget_get_allocation (widget, &allocation); + cairo_translate (cr, allocation.x, allocation.y); + + gboolean result = sp_ruler_draw (widget, cr); + + cairo_destroy (cr); + + return result; +} #endif + + + +static gboolean sp_ruler_draw(GtkWidget *widget, + cairo_t *cr) { - SPRuler *ruler = SP_RULER (widget); - SPRulerPrivate *priv = ruler->priv; + SPRuler *ruler = SP_RULER (widget); + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler); + + sp_ruler_draw_ticks (ruler); -#if GTK_CHECK_VERSION(3,0,0) cairo_set_source_surface(cr, priv->backing_store, 0, 0); cairo_paint(cr); -#else - cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(widget)); - gdk_cairo_set_source_pixmap(cr, priv->backing_store, 0, 0); - gdk_cairo_region(cr, event->region); - cairo_fill(cr); -#endif - - if (SP_RULER_GET_CLASS(ruler)->draw_pos) - SP_RULER_GET_CLASS(ruler)->draw_pos(ruler, cr); -#if !GTK_CHECK_VERSION(3,0,0) - cairo_destroy (cr); -#endif + sp_ruler_draw_pos (ruler); return FALSE; } -static void sp_ruler_make_pixmap(SPRuler *ruler) + +static void +sp_ruler_make_pixmap (SPRuler *ruler) { - SPRulerPrivate *priv = ruler->priv; - GtkWidget *widget = GTK_WIDGET(ruler); + GtkWidget *widget = GTK_WIDGET (ruler); + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler); + GtkAllocation allocation; - GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); if (priv->backing_store) -#if GTK_CHECK_VERSION(3,0,0) - cairo_surface_destroy(priv->backing_store); + cairo_surface_destroy (priv->backing_store); - priv->backing_store = gdk_window_create_similar_surface(gtk_widget_get_window(widget), - CAIRO_CONTENT_COLOR, - allocation.width, - allocation.height); -#else - g_object_unref(priv->backing_store); + priv->backing_store = + gdk_window_create_similar_surface (gtk_widget_get_window (widget), + CAIRO_CONTENT_COLOR, + allocation.width, + allocation.height); +} - priv->backing_store = gdk_pixmap_new(gtk_widget_get_window(widget), - allocation.width, - allocation.height, - -1); -#endif - priv->xsrc = 0; - priv->ysrc = 0; +static void +sp_ruler_draw_pos (SPRuler *ruler) +{ + GtkWidget *widget = GTK_WIDGET (ruler); - sp_ruler_draw_ticks(ruler); -} +#if GTK_CHECK_VERSION(3,0,0) + GtkStyleContext *context = gtk_widget_get_style_context (widget); + GtkBorder border; + GdkRGBA color; +#else + GtkStyle *style = gtk_widget_get_style (widget); + GtkStateType state = gtk_widget_get_state (widget); + gint xthickness; + gint ythickness; +#endif + + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler); + GtkAllocation allocation; + gint x, y; + gint width, height; + gint bs_width, bs_height; + if (! gtk_widget_is_drawable (widget)) + return; -static void sp_ruler_real_draw_pos(SPRuler *ruler, - cairo_t *cr) -{ - GtkAllocation allocation; - GtkWidget *widget = GTK_WIDGET (ruler); - SPRulerPrivate *priv = ruler->priv; - gint x, y; - gint bs_width, bs_height; - gdouble increment; - - GtkStyle *style = gtk_widget_get_style(widget); gtk_widget_get_allocation(widget, &allocation); - gint xthickness = style->xthickness; - gint ythickness = style->ythickness; - gint width = allocation.width; - gint height = allocation.height; +#if GTK_CHECK_VERSION(3,0,0) + gtk_style_context_get_border (context, static_cast<GtkStateFlags>(0), &border); +#else + xthickness = style->xthickness; + ythickness = style->ythickness; +#endif if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) { - height -= ythickness * 2; + width = allocation.width; +#if GTK_CHECK_VERSION(3,0,0) + height = allocation.height - (border.top + border.bottom); +#else + height = allocation.height - ythickness * 2; +#endif bs_width = height / 2 + 2; bs_width |= 1; /* make sure it's odd */ @@ -666,7 +673,12 @@ static void sp_ruler_real_draw_pos(SPRuler *ruler, } else { - width -= xthickness * 2; +#if GTK_CHECK_VERSION(3,0,0) + width = allocation.width - (border.left + border.right); +#else + width = allocation.width - xthickness * 2; +#endif + height = allocation.height; bs_height = width / 2 + 2; bs_height |= 1; /* make sure it's odd */ @@ -675,28 +687,62 @@ static void sp_ruler_real_draw_pos(SPRuler *ruler, if ((bs_width > 0) && (bs_height > 0)) { + cairo_t *cr = gdk_cairo_create (gtk_widget_get_window (widget)); + gdouble lower; + gdouble upper; + gdouble position; + gdouble increment; + + cairo_rectangle (cr, + allocation.x, allocation.y, + allocation.width, allocation.height); + cairo_clip (cr); + + cairo_translate (cr, allocation.x, allocation.y); + + /* If a backing store exists, restore the ruler */ + if (priv->backing_store) + { + cairo_set_source_surface (cr, priv->backing_store, 0, 0); + cairo_rectangle (cr, priv->xsrc, priv->ysrc, bs_width, bs_height); + cairo_fill (cr); + } + + position = sp_ruler_get_position (ruler); + + sp_ruler_get_range (ruler, &lower, &upper, NULL); + if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) { - increment = (gdouble) width / (priv->upper - priv->lower); + increment = (gdouble) width / (upper - lower); - x = ROUND ((priv->position - priv->lower) * increment) + (xthickness - bs_width) / 2 - 1; +#if GTK_CHECK_VERSION(3,0,0) + x = ROUND ((position - lower) * increment) + (border.left - bs_width) / 2 - 1; + y = (height + bs_height) / 2 + border.top; +#else + x = ROUND ((position - lower) * increment) + (xthickness - bs_width) / 2 - 1; y = (height + bs_height) / 2 + ythickness; +#endif } else { - increment = (gdouble) height / (priv->upper - priv->lower); + increment = (gdouble) height / (upper - lower); +#if GTK_CHECK_VERSION(3,0,0) + x = (width + bs_width) / 2 + border.left; + y = ROUND ((position - lower) * increment) + (border.top - bs_height) / 2 - 1; +#else x = (width + bs_width) / 2 + xthickness; - y = ROUND ((priv->position - priv->lower) * increment) + (ythickness - bs_height) / 2 - 1; + y = ROUND ((position - lower) * increment) + (ythickness - bs_height) / 2 - 1; +#endif } #if GTK_CHECK_VERSION(3,0,0) - GtkStyleContext *sc = gtk_widget_get_style_context(widget); - GdkRGBA color; - gtk_style_context_get_color(sc, gtk_widget_get_state_flags(widget), &color); - gdk_cairo_set_source_rgba(cr, &color); + gtk_style_context_get_color (context, gtk_widget_get_state_flags (widget), + &color); + gdk_cairo_set_source_rgba (cr, &color); #else - gdk_cairo_set_source_color(cr, &style->fg[gtk_widget_get_state(widget)]); + gdk_cairo_set_source_color (cr, &style->fg[state]); #endif cairo_move_to (cr, x, y); @@ -714,6 +760,8 @@ static void sp_ruler_real_draw_pos(SPRuler *ruler, cairo_fill (cr); + cairo_destroy (cr); + priv->xsrc = x; priv->ysrc = y; } @@ -729,12 +777,53 @@ GtkWidget* sp_ruler_new(GtkOrientation orientation) NULL)); } + +/** + * sp_ruler_set_position: + * @ruler: a #SPRuler + * @position: the position to set the ruler to + * + * This sets the position of the ruler. + */ +void +sp_ruler_set_position (SPRuler *ruler, + gdouble position) +{ + SPRulerPrivate *priv; + + g_return_if_fail (SP_IS_RULER (ruler)); + + priv = SP_RULER_GET_PRIVATE (ruler); + + if (priv->position != position) + { + priv->position = position; + g_object_notify (G_OBJECT (ruler), "position"); + + sp_ruler_draw_pos (ruler); + } +} + +/** + * sp_ruler_get_position: + * @ruler: a #SPRuler + * + * Return value: the current position of the @ruler widget. + */ +gdouble +sp_ruler_get_position (SPRuler *ruler) +{ + g_return_val_if_fail (SP_IS_RULER (ruler), 0.0); + + return SP_RULER_GET_PRIVATE (ruler)->position; +} + static gboolean sp_ruler_motion_notify(GtkWidget *widget, GdkEventMotion *event) { GtkAllocation allocation; SPRuler *ruler = SP_RULER(widget); - SPRulerPrivate *priv = ruler->priv; + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler); gdk_event_request_motions(event); gint x = event->x; @@ -754,20 +843,33 @@ static gboolean sp_ruler_motion_notify(GtkWidget *widget, return FALSE; } -static void sp_ruler_real_draw_ticks(SPRuler *ruler, cairo_t *cr) +static void sp_ruler_draw_ticks(SPRuler *ruler) { - SPRulerPrivate *priv = ruler->priv; - gint width = 0; - gint height = 0; - gchar unit_str[32]; - gchar digit_str[2] = { '\0', '\0' }; - GtkOrientation orientation; - GtkAllocation allocation; + GtkWidget *widget = GTK_WIDGET (ruler); + +#if GTK_CHECK_VERSION(3,0,0) + GtkStyleContext *context = gtk_widget_get_style_context (widget); + GtkStateFlags state = gtk_widget_get_state_flags (widget); + GtkBorder border; +#else + GtkStyle *style = gtk_widget_get_style (widget); + GtkStateType state = gtk_widget_get_state (widget); +#endif + + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler); + GtkAllocation allocation; + cairo_t *cr = cairo_create(priv->backing_store); + gint width = 0; + gint height = 0; + gint length; + gdouble increment; /* Number of pixels per unit */ + gint scale; /* Number of units per major unit */ + gchar unit_str[32]; + gchar digit_str[2] = { '\0', '\0' }; + gint text_size; g_return_if_fail (ruler != NULL); - g_object_get(G_OBJECT(ruler), "orientation", &orientation, NULL); - GtkWidget *widget = GTK_WIDGET (ruler); PangoContext *pango_context = gtk_widget_get_pango_context (widget); PangoLayout *pango_layout = pango_layout_new (pango_context); @@ -779,21 +881,15 @@ static void sp_ruler_real_draw_ticks(SPRuler *ruler, cairo_t *cr) gint digit_height = (int) floor (RULER_FONT_SIZE * RULER_FONT_VERTICAL_SPACING / PANGO_SCALE + 0.5); #if GTK_CHECK_VERSION(3,0,0) - GtkStyleContext *context = gtk_widget_get_style_context(widget); - GtkStateFlags state = gtk_widget_get_state_flags(widget); - GtkBorder padding; - gtk_style_context_get_padding(context, state, &padding); - gint xthickness = padding.left; - gint ythickness = padding.top; + gtk_style_context_get_border (context, static_cast<GtkStateFlags>(0), &border); #else - GtkStyle *style = gtk_widget_get_style(widget); gint xthickness = style->xthickness; gint ythickness = style->ythickness; #endif gtk_widget_get_allocation (widget, &allocation); - if (orientation == GTK_ORIENTATION_HORIZONTAL) { + if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) { width = allocation.width; // in pixels; is apparently 2 pixels shorter than the canvas at each end height = allocation.height; } else { @@ -802,33 +898,25 @@ static void sp_ruler_real_draw_ticks(SPRuler *ruler, cairo_t *cr) } #if GTK_CHECK_VERSION(3,0,0) - gtk_render_frame(context, - cr, - 0, 0, - allocation.width, allocation.height); - - gtk_render_background(context, - cr, - 0, 0, - allocation.width, allocation.height); + GdkRGBA color; + gtk_style_context_get_background_color(context, + state, + &color); + gdk_cairo_set_source_rgba(cr, &color); #else - gtk_paint_box(style, priv->backing_store, - GTK_STATE_NORMAL, GTK_SHADOW_NONE, NULL, widget, - orientation == GTK_ORIENTATION_HORIZONTAL ? "hruler" : "vruler", - 0, 0, - allocation.width, allocation.height); + gdk_cairo_set_source_color(cr, &style->bg[state]); #endif + cairo_paint(cr); cairo_set_line_width(cr, 1.0); #if GTK_CHECK_VERSION(3,0,0) - GdkRGBA color; gtk_style_context_get_color(context, - gtk_widget_get_state_flags(widget), + state, &color); gdk_cairo_set_source_rgba(cr, &color); #else - gdk_cairo_set_source_color(cr, &style->fg[gtk_widget_get_state(widget)]); + gdk_cairo_set_source_color(cr, &style->fg[state]); #endif gdouble upper = priv->upper / priv->metric->pixels_per_unit; // upper and lower are expressed in ruler units @@ -837,9 +925,9 @@ static void sp_ruler_real_draw_ticks(SPRuler *ruler, cairo_t *cr) * in 1/72nd's of an inch and has nothing to do with screen pixels */ if ((upper - lower) == 0) - return; + goto out; - double increment = (double) (width + 2*UNUSED_PIXELS) / (upper - lower); // screen pixels per ruler unit + increment = (gdouble) (width + 2*UNUSED_PIXELS) / (upper - lower); // screen pixels per ruler unit /* determine the scale * For vruler, use the maximum extents of the ruler to determine the largest @@ -850,19 +938,19 @@ static void sp_ruler_real_draw_ticks(SPRuler *ruler, cairo_t *cr) * text_width = gdk_string_width(font, unit_str), so that the result * for the scale looks consistent with an accompanying vruler */ - gint scale = (int)(ceil(priv->max_size / priv->metric->pixels_per_unit)); + scale = (gint)(ceil(priv->max_size / priv->metric->pixels_per_unit)); sprintf (unit_str, "%d", scale); - gint text_dimension = strlen (unit_str) * digit_height + 1; + text_size = strlen (unit_str) * digit_height + 1; for (scale = 0; scale < MAXIMUM_SCALES; scale++) - if (priv->metric->ruler_scale[scale] * fabs(increment) > 2 * text_dimension) + if (priv->metric->ruler_scale[scale] * fabs(increment) > 2 * text_size) break; if (scale == MAXIMUM_SCALES) scale = MAXIMUM_SCALES - 1; /* drawing starts here */ - gint length = 0; + length = 0; for (gint i = MAXIMUM_SUBDIVIDE - 1; i >= 0; i--) { double subd_incr = priv->metric->ruler_scale[scale] / priv->metric->subdivide[i]; @@ -896,13 +984,23 @@ static void sp_ruler_real_draw_ticks(SPRuler *ruler, cairo_t *cr) // by a pixel, and jump back on the next redraw). This is suppressed by adding 1e-9 (that's only one nanopixel ;-)) gint pos = int(Inkscape::round((cur - lower) * increment + 1e-12)) - UNUSED_PIXELS; - if (orientation == GTK_ORIENTATION_HORIZONTAL) { +#if GTK_CHECK_VERSION(3,0,0) + if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) { + cairo_move_to(cr, pos+0.5, height + border.top); + cairo_line_to(cr, pos+0.5, height - length + border.bottom); + } else { + cairo_move_to(cr, height + border.left - length, pos+0.5); + cairo_line_to(cr, height + border.right, pos+0.5); + } +#else + if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) { cairo_move_to(cr, pos+0.5, height + ythickness); cairo_line_to(cr, pos+0.5, height - length + ythickness); } else { cairo_move_to(cr, height + xthickness - length, pos+0.5); cairo_line_to(cr, height + xthickness, pos+0.5); } +#endif /* draw label */ double label_spacing_px = fabs((increment*(double)priv->metric->ruler_scale[scale])/priv->metric->subdivide[i]); @@ -915,7 +1013,7 @@ static void sp_ruler_real_draw_ticks(SPRuler *ruler, cairo_t *cr) else sprintf (unit_str, "%d", (int) cur); - if (orientation == GTK_ORIENTATION_HORIZONTAL) { + if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) { pango_layout_set_text (pango_layout, unit_str, -1); cairo_move_to(cr, pos+2, 0); pango_cairo_show_layout(cr, pango_layout); @@ -923,7 +1021,11 @@ static void sp_ruler_real_draw_ticks(SPRuler *ruler, cairo_t *cr) for (gint j = 0; j < (int) strlen (unit_str); j++) { digit_str[0] = unit_str[j]; pango_layout_set_text (pango_layout, digit_str, 1); +#if GTK_CHECK_VERSION(3,0,0) + cairo_move_to(cr, border.left + 1, pos + digit_height * (j) + 1); +#else cairo_move_to(cr, xthickness + 1, pos + digit_height * (j) + 1); +#endif pango_cairo_show_layout(cr, pango_layout); } } @@ -938,6 +1040,11 @@ static void sp_ruler_real_draw_ticks(SPRuler *ruler, cairo_t *cr) cairo_stroke(cr); } } + + cairo_fill (cr); + +out: + cairo_destroy (cr); } @@ -946,7 +1053,7 @@ void sp_ruler_set_metric(SPRuler *ruler, SPMetric metric) g_return_if_fail(ruler != NULL); g_return_if_fail(SP_IS_RULER (ruler)); g_return_if_fail((unsigned) metric < G_N_ELEMENTS(sp_ruler_metrics)); - SPRulerPrivate *priv = ruler->priv; + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler); if (metric == 0) return; @@ -955,5 +1062,16 @@ void sp_ruler_set_metric(SPRuler *ruler, SPMetric metric) g_object_notify(G_OBJECT(ruler), "metric"); - sp_ruler_invalidate_ticks(ruler); + gtk_widget_queue_draw (GTK_WIDGET (ruler)); } + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : |
